浏览到chnking的WCF的分布式事务处理不错,转载过来分享一下。

1、 WCF分布式事务例子
这里也用转账的例子说事。
用户在系统A和系统B都有账户,账户间的资金可以互转,系统A的资金减少多少,系统B的相应账户的资金就增加多少。
系统A机器上有数据库AccountA,系统B机器上有数据库AccountB,数据库的结构一样,都有一个数据表Account,结构如下:

 [转载]WCF系列_分布式事务(下)
为了演示TxF事务性文件,在系统B中增加了一个写文件的操作,记录本次转账操作的信息。转账的所有操作步骤:系统A上账户上减少金额,系统B上记录转账信息文件,系统B上相应账户资金增加这三个操作都在一个事务流中,要么全部完成,要么全部回滚。
系统A和系统B分别在服务器A和服务器B上。系统A在账户上减少金额后调用系统B的WCF服务,在系统B中继续增加账户资金,生成转账信息文件。

下面开始这个例子的完整过程。
1.1.   建立系统B转账WCF服务
建立服务契约:
[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的客户端没有事务流则抛出异常。

下面是服务实现:

 1 [ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
 2 
 3 public class AccountBService : IAccountB
 4 
 5 {
 6 
 7     [OperationBehavior(TransactionScopeRequired = true)]
 8 
 9     public void deposit(int depositorid, double amount)
10 
11     {
12 
13         #region 新建事务性文件
14 
15         string path = @"c:\test.txt";
16 
17         FileStream fs = TransactedFile.Open(path, System.IO.FileMode.Create,
18 
19             System.IO.FileAccess.ReadWrite, System.IO.FileShare.ReadWrite);
20 
21         string fileContent = string.Format("从系统A转账到系统B\r\n用户ID:{0}\r\n转账金额为:{1}",            depositorid.ToString(), amount.ToString());
22 
23         byte[] byteArrar = Encoding.UTF8.GetBytes(fileContent);
24 
25         fs.Write(byteArrar, 0, byteArrar.Count());
26 
27         fs.Flush();
28 
29         fs.Close();
30 
31         #endregion
32 
33  
34 
35         #region 数据访问,在指定账户上增加存款
36 
37         string connstr = ConfigurationManager.ConnectionStrings["ConnStr"].ToString();
38 
39         SqlCommand mySqlCommand = new SqlCommand("update account set amount = amount +        @amount where depositorid = @depositorid ");
40 
41         mySqlCommand.Connection = new SqlConnection(connstr);
42 
43         SqlParameter par1 = new SqlParameter("@amount", SqlDbType.Decimal);
44 
45         par1.Value = amount;
46 
47         mySqlCommand.Parameters.Add(par1);
48 
49         par1 = new SqlParameter("@depositorid", SqlDbType.Int);
50 
51         par1.Value = depositorid;
52 
53         mySqlCommand.Parameters.Add(par1);
54 
55         mySqlCommand.Connection.Open();
56 
57         mySqlCommand.ExecuteNonQuery();
58 
59         mySqlCommand.Connection.Close();
60 
61         #endregion
62 
63      }
64 
65 }
View Code

服务实现了deposit操作。
[OperationBehavior(TransactionScopeRequired = true)],这里的TransactionScopeRequired = true表示这个操作在TransactionScope内执行,加上前面OperationContract上的TransactionFlowOption.Allowed 允许跟随事务的设置,这个deposit的操作将会参与客户端发起的分布式事务。
实现的deposit操作中完成两个任务,先转账信息写入c:\test.txt文件,这里写文件操作使用了TxF事务性文件操作TransactedFile.Open,关于TxF的操作部分的代码微软有提供,在本文中提供的代码中包含了这部分源码。使用事务性文件操作,在事务中的其他事务资源操作失败后,文件操作也会回滚。

1.2.   建立系统A转账客户端
系统A是个Console应用:

相关文章: