WCF – 交易
WCF – 交易
WCF 中的事务是一组遵循某些属性的操作,统称为 ACID。在这里,如果单个操作失败,整个系统就会自动失败。当在线下订单时,就会发生交易。以下示例有助于以更简单的方式理解交易过程。
例子
假设您从网上商店订购了一台液晶电视,并且您将使用信用卡支付金额。当您输入下订单的必要信息时,两个操作同时发生。
一是从您的银行账户中扣除指定金额,二是供应商账户贷记相同金额。这两个操作都必须成功执行才能成功进行交易。
WCF 事务属性
WCF 事务后跟的四个属性如下 –
-
Atomic – 所有操作必须在交易完成时作为一个不可分割的操作。
-
一致性– 无论操作集是什么,系统始终处于一致性状态,即事务的结果始终符合预期。
-
隔离– 在交易完成之前,系统的中间状态对外部世界的任何实体都是不可见的。
-
耐用性– 无论出现任何类型的故障(硬件、断电等),都将保持承诺状态
在配置 WCF 事务时,需要考虑一些因素。这些是绑定和操作行为。
Binding – WCF 中支持事务的绑定只有少数几个,并且仅从这些绑定中进行选择至关重要,这些绑定在默认情况下保持禁用状态,应该启用以获得对事务的必要支持。这些绑定如下 –
- 网络协议绑定
- 网络命名管道绑定
- WSHttp绑定
- WSDualHttpBinding
- WSFederationHttpBinding
操作行为– 虽然绑定促进了事务传播的路径,但操作负责事务处理以及操作配置。操作行为主要使用两个属性:TransactionFlow 和 TransactionScopeRequired。这里需要注意的是,TransactionFlow 主要有三个值,它们是:Allowed、Mandatory 和 NotAllowed。
下面的代码展示了改变绑定和操作合约的配置是否有利于客户端的传播。
<bindings> <wsHttpBinding> <binding name = "MandatoryTransBinding" transactionFlow = "true"> <reliableSession enabled ="true"/> </binding> </wsHttpBinding> </bindings>
交易协议
WCF 使用三种类型的协议进行交易 –
- 轻的
- 奥莱交易
- WS-原子事务 (WS-AT)
在这三者中,WS-AT 是一种可互操作的协议,支持跨防火墙的分布式事务流。但是,当交易严格基于 Microsoft 技术时,不应使用此协议。
WCF 事务的阶段
WCF 事务有两个阶段,如下图所示。
-
准备阶段– 在此阶段,事务管理器检查所有实体是否已准备好提交事务。
-
提交阶段– 在此阶段,实体的承诺在现实中开始。
下图说明了 WCF 事务的两个阶段的功能。
启用 WCF 事务
要成功启用 WCF 事务,需要按顺序执行一系列六个步骤。下面讨论必要的步骤。
步骤 1 – 创建两个 WCF 服务
这方面的首要步骤是在 WCF 中构建两个服务项目以参与单个事务。数据库事务将在这两个服务上执行,并且可以理解它们是如何通过 WCF 事务统一的。还创建了 WCFTransactions 的 Web 应用程序,以在单个事务范围内使用这两个创建的服务。
步骤 2 – 方法创建及其具有 TransactionFlow 属性的属性
在这里,将为两个 WCF 服务创建一个 UpdateData 方法,以将其插入到具有 OperationContract 属性的数据库中。为了完成这个任务,首先在 ServiceContract 属性的帮助下创建一个接口类。为了在新创建的方法中启用事务,它被归因于 TransactionFlow 并且允许事务使用是 Allowed 值。
[ServiceContract] public interface IService1 { [OperationContract] [TransactionFlow(TransactionFlowOption.Allowed)] void UpdateData(); }
第 3 步 – 使用 TransactionScopeRequired 属性实现 WCF 服务
它是通过使用下面显示的代码完成的 –
[OperationBehavior(TransactionScopeRequired = true)] public void UpdateData() { try { SqlConnection objConnection = new SqlConnection(strConnection); objConnection.Open(); using(SqlTransaction transaction = Program.dbConnection.BeginTransaction()) { Boolean doRollback = false; using(SqlCommand cmd = new SqlCommand( "insert into Customer (Customer name, Customer code) values ('sss', 'sss')"objConnection)) try { cmd.ExecuteNonQuery(); } catch(SqlException) { doRollback = true; break; } } if(doRollback) transaction.Rollback(); else transaction.Commit(); } finally { objConection.Close(); } }
第 4 步 – 通过 WCF 服务配置文件启用事务流
其编码如下 –
<bindings> <wsHttpBinding> <binding name = "TransactionalBind" transactionFlow = "true"/> </wsHttpBinding> </bindings>
将事务允许绑定附加到端点以公开 WCF 服务至关重要。
<endpoint address = "" binding = "wsHttpBinding" bindingConfiguration = "TransactionalBind" contract = "WcfService1.IService1">
第 5 步 – 在单个事务中调用这两个服务
在这里,上述两个服务在一个事务中调用,为此,TransactionScope 对象用于对这两个服务进行分组。调用上述对象的 Complete 方法来提交 WCF 事务。要回滚,将调用 Dispose 方法。
using (TransactionScope ts = new TransactionScope(TransactionScopeOption.RequiresNew)) { try { // Call your webservice transactions here ts.Complete(); } catch (Exception ex) { ts.Dispose(); } }
将 WCF 事务分组到一个范围内的一小段完整代码如下所示 –
using (TransactionScope ts = new TransactionScope(TransactionScopeOption.RequiresNew)) { try { ServiceReference1.Service1Client obj = newServiceReference1.Service1Client(); obj.UpdateData(); ServiceReference2.Service1Client obj1 = new ServiceReference2.Service1Client(); obj1.UpdateData(); ts.Complete(); } catch (Exception ex) { ts.Dispose(); } }
第 6 步 – 测试 WCF 事务
测试在第 6 步也是最后一步完成,在调用第一个 WCF 服务后,会强制发生异常。