logo

详细wcf编程之wcf分布式事务实例应用篇

时间:2010-1-10 14:39:18 来源:www.cnblogs.com 作者:chnking

在上一篇详细讲解wcf编程分布式事务应用理论篇 ,我们讲解了一些wcf分布式事务的理论知识,那么接着我们就来一下wcf分布式事务例子吧。这样更加入解wcf的应用。

1、 WCF分布式事务例子

这里也用转账的例子说事。

用户在系统A和系统B都有账户,账户间的资金可以互转,系统A的资金减少多少,系统B的相应账户的资金就增加多少。

系统A机器上有数据库AccountA,系统B机器上有数据库AccountB,数据库的结构一样,都有一个数据表Account,结构如下:

字段

数据类型

含义

depositorID

int

账户id

amount

decimal(18, 2)

金额

 

为了演示TxF事务性文件,在系统B中增加了一个写文件的操作,记录本次转账操作的信息。转账的所有操作步骤:系统A上账户上减少金额,系统B上记录转账信息文件,系统B上相应账户资金增加这三个操作都在一个事务流中,要么全部完成,要么全部回滚。

系统A和系统B分别在服务器A和服务器B上。系统A在账户上减少金额后调用系统B的WCF服务,在系统B中继续增加账户资金,生成转账信息文件。

下面开始这个例子的完整过程。

1.1.   建立系统B转账WCF服务

建立服务契约:

Code [http://www.xueit.com]
[ServiceContract] public interface IAccountB { [OperationContract] [TransactionFlow(TransactionFlowOption.Allowed)] void deposit(int depositorid, double amount); }

服务契约就一个方法deposit,其中depositorid表示账户id,amount表示要从系统A转账到系统B的金额。

TransactionFlow这个属性指示operation是否跟随调用端的事务流,参数含义:

TransactionFlowOption.NotAllowed – 表示此operation不跟随传入的事务流,不参与分布式事务。

TransactionFlowOption.Allowed – 表示此opreation可以跟随传入的事务流,如果有传入的事务流则参与,如果没有传入的事务流则不参与,但是可以启动本地的事务。

TransactionFlowOption.Mandatory – 表示此operation必须跟随传入的事务,参与分布式事务,如果调用此operation的客户端没有事务流则抛出异常。

下面是服务实现:

Code [http://www.xueit.com]
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)] public class AccountBService : IAccountB { [OperationBehavior(TransactionScopeRequired = true)] public void deposit(int depositorid, double amount) { #region 新建事务性文件 string path = @"c:\test.txt"; FileStream fs = TransactedFile.Open(path, System.IO.FileMode.Create, System.IO.FileAccess.ReadWrite, System.IO.FileShare.ReadWrite); string fileContent = string.Format("从系统A转账到系统B\r\n用户ID:{0}\r\n转账金额为:{1}", depositorid.ToString(), amount.ToString()); byte[] byteArrar = Encoding.UTF8.GetBytes(fileContent); fs.Write(byteArrar, 0, byteArrar.Count()); fs.Flush(); fs.Close(); #endregion #region 数据访问,在指定账户上增加存款 string connstr = ConfigurationManager.ConnectionStrings["ConnStr"].ToString(); SqlCommand mySqlCommand = new SqlCommand("update account set amount = amount @amount where depositorid = @depositorid "); mySqlCommand.Connection = new SqlConnection(connstr); SqlParameter par1 = new SqlParameter("@amount", SqlDbType.Decimal); par1.Value = amount; mySqlCommand.Parameters.Add(par1); par1 = new SqlParameter("@depositorid", SqlDbType.Int); par1.Value = depositorid; mySqlCommand.Parameters.Add(par1); mySqlCommand.Connection.Open(); mySqlCommand.ExecuteNonQuery(); mySqlCommand.Connection.Close(); #endregion } }

服务实现了deposit操作。

[OperationBehavior(TransactionScopeRequired = true)],这里的TransactionScopeRequired = true表示这个操作在TransactionScope内执行,加上前面OperationContract上的TransactionFlowOption.Allowed 允许跟随事务的设置,这个deposit的操作将会参与客户端发起的分布式事务。

实现的deposit操作中完成两个任务,先转账信息写入c:\test.txt文件,这里写文件操作使用了TxF事务性文件操作TransactedFile.Open,关于TxF的操作部分的代码微软有提供,在本文中提供的代码中包含了这部分源码。使用事务性文件操作,在事务中的其他事务资源操作失败后,文件操作也会回滚。

1.2.   建立系统A转账客户端

系统A是个Console应用:

Code [http://www.xueit.com]
static void Main(string[] args) { ChannelFactory<IAccountB> myFactory = new ChannelFactory<IAccountB>("endpointConfig"); IAccountB myClient = myFactory.CreateChannel(); Double amount = 500; int depositorid = 1; using (TransactionScope scop = new TransactionScope()) { #region 数据访问,在指定账户上减少存款 string connstr = ConfigurationManager.ConnectionStrings["ConnStr"].ToString(); SqlCommand mySqlCommand = new SqlCommand("update account set amount = amount - @amount where depositorid = @depositorid "); mySqlCommand.Connection = new SqlConnection(connstr); SqlParameter par1 = new SqlParameter("@amount", SqlDbType.Decimal); par1.Value = amount; mySqlCommand.Parameters.Add(par1); par1 = new SqlParameter("@depositorid", SqlDbType.Int); par1.Value = depositorid; mySqlCommand.Parameters.Add(par1); mySqlCommand.Connection.Open(); mySqlCommand.ExecuteNonQuery(); mySqlCommand.Connection.Close(); #endregion try { myClient.deposit(depositorid, amount); scop.Complete(); } catch (Exception e) { Transaction.Current.Rollback(); } } }


文章分页123
标签:wcf编程,分布式事务
100%

回复:详细wcf编程之wcf分布式事务实例应用篇

0 / 5000