整体来讲,WCF开发人员不须要涉及事务协议与管理器。咱们应该依赖WCF来选择相应的事务协议和管理器,重点关注业务逻辑的实现。编程
WCF是根据事务范围里的参与个体来选择事务管理协议的。事务管理协议之间的差异与远程调用、通行协议,以及跨越的系统边界有关。跨域
可选择的管理协议以下:网络
轻量级事务协议
这个协议只在本地同一个应用程序域内的上下文环境里管理事务,他不能跨越应用程序边界来传播事务(更不能跨越进程或机器边界了),也不能跨越服务边界(从客户端到服务段)。轻量级协议只能在单个服务内部或同一个应用程序域里的两个个体间使用。与其它协议相比,轻量级协议拥有最佳的性能。分布式
OleTx事务协议
这个协议能够跨域应用程序域、进程和机器边界来传播事务,而且能够管理两阶段提交协议。协议使用RPC调用,而且消息格式是Windows指定的二进制格式。由于这个缘由,他不能跨越防火墙,也不能与非Windows平台的系统交互。这一般不能问题所在,应为OleTx进程用于Intranet里,并且是相同的Windows环境下。性能
WSAT事务协议
这个协议和OleTx事务协议同样,能够跨域应用程序域、进程和机器边界来传播事务,而且能够管理两阶段提交协议。可是,WSAT事务协议基于行业标准,并可以穿越防火墙。推荐在Internet上有多个事务管理器参与事务时使用这种协议。优化
没有绑定支持轻量级事务协议,由于该协议没法跨域服务边界传播。TCP和IPC绑定能够配置为同时使用OleTx和WSAT事务协议,或者使用二者之一。两个绑定默认使用OlxTx事务协议,在须要的时候会切换为WSAT事务协议。spa
此外,这些Intranet绑定容许使用配置文件或代码来配置事务协议,这一点和其它的绑定属性一致。设计
WCF提供了抽象类TransactionProtocol,定义以下:代理
// 指定在流动事务中使用的事务处理协议。 public abstract class TransactionProtocol { // 初始化 System.ServiceModel.TransactionProtocol 类的新实例。 protected TransactionProtocol(); // 获取事务处理协议的默认值。 public static TransactionProtocol Default { get; } // 获取 OleTransactions 事务处理协议值。 public static TransactionProtocol OleTransactions { get; } // 获取 WSAtomicTransaction11 事务处理协议值。 public static TransactionProtocol WSAtomicTransaction11 { get; } // 获取 WSAtomicTransactionOctober2004 事务处理协议值。 public static TransactionProtocol WSAtomicTransactionOctober2004 { get; } }TCP和IPC都提供了TransactionProtocol属性。例如:code
public class NetTcpBinding : Binding,... { TransactionProtocal TransactionProtocal { get; set } ...... }
采用编程方式设置协议,首先须要构建须要的绑定类型,而后使用某个静态方法来设置属性:
NetTcpBinding bingding = new NetTcpBinding(); //支持传播事务的协议 bingding.TransactionFlow = true; bingding.TransactionProtocol = TransactionProtocol.WSAtomicTransactionOctober2004;注意,事务协议配置只有在启用事务传播的时候才有意义。配置文件里配置事务协议以下:
当为TCP和IPC绑定配置事务协议时,服务和客户端必须使用相同的协议。因为TCP和IPC绑定只能在Intranet内部使用,所以配置为WSAT事务协议并没什么实际意义。
WS绑定(WsSHttpBinding、WS2007HttpBinding、WSDualHttpBinding等等)都是为了Internet设计的,当须要多个事务管理器协调工做时,就应该使用WSAT事务协议。可是,当Internet只有一个事务管理器时,这些绑定默认都使用OleTx事务协议。这里不必配置特别的事务协议。
若是管理事务呢?最佳的解决方案就是使用一个名叫事务管理器的第三方来完成这个工做,由它来负责为客户端和服务端两个两阶段提交协议。
事务管理器是整个事务控制模型的核心和枢纽,是它控制着事务的全部参与者,协调整个事务从开始到完成的全部相关处理流程。事务管理器为应用和资源管理器提供一系列核心的事务性的服务,实现事务的开始、提交和回滚。Windows提供了三种不一样的事务管理器,以下图所示:
上图所示的三个事务管理器就是轻量级事务管理器(LTM),核心事务管理器(KTM)和分布式事务、协调器(DTC)。做为平台使用的功能、应用程序要作的工做、调用的服务、使用的资源,.NET都会自动分配合适的事务管理器。由于分配工做是自动完成的,因此代码就看能够从事务管理和事务协议之间解耦了。再次重申,开发人员历来不须要为事务管理器烦恼。
轻量级事务管理器(LTM: Lightweight Transaction Manager)
正如其名称隐含的意思,轻量级事务管理器(如下简称LTM)具备最小的负载,是性能最高的事务管理器。
LTM的做用范围仅限于开启事务的应用程序域(AppDomain)中,而且登记到事务中的持久化资源(Durable Resource)数量不能超过一个。
通常地,被开启的事务就由LTM管理,若是事务涉及到跨应用程序域的操做,当前的事务回被奉送、传播到另外一个执行上下文中,此时事务将脱离LTM的管辖。
此外,基于LTM的事务中能够同时登记(Enlist)多个易失型资源(Volatile),可是仅仅容许登记惟一一个持久化资源。当第二个持久化资源被登记到当前事务中,该事务也将脱离LTM的管辖。
若是只有单个资源管理器,而且资源支持单阶段提交协议,LTM会使用优化协议。更为重要的是,LTM只能管理单个服务内的事务,不支持事务流传播。
LTM是最小的事务管理器,它能够直接在资源上执行事务操做。
内核事务管理器(KTM:Kernel transaction Manager)
内核事务管理器(如下简称KTM)在Windows Vista中被引入,并被用于后续的Windows Server 2008和Windows 7。引入KTM的主要的目的在于实现将文件管理和注册表管理归入事务的范畴。借助于KTM,咱们能够以事务的方式操做NTFS文件系统下的文件资源,以及注册表资源。咱们将支持事务的文件系统和注册表成为事务型的文件系统(TxF)和事务型注册表(TxR)。
之因此被称为内核事务管理器,使由于基于KTM的事务控制引擎运行在内核模式(Kernel Mode),而不是用户模式(User Mode)下。
KTM在内存中调用时使用轻量级事务协议。KTM之多能够管理一个持久化的内核资源管理器(KTM)事务,可是能够管理多个易失型事务资源管理器。
使用KTM时至多可使用一个服务,但不是传播事务。
分布式事务协调器(DTC:Distributed Transaction Coordinator)
DTC用于管理跨边界(跨应用程序域、进程、机器以致跨网络)执行的分布式事务,它采用相应的事务管理协议,好比OleTx和WSAT,协调一个分布式事务中的全部参与者。
在事务流跨越服务边界时,会使用DTC做为事务管理器,它能够管理包含多个服务和资源管理器的事务。
在每台容许WCF的机器上,DTC默认都是可用的,WCF紧密的与DTC继承在一块儿。他负责建立事务,收集资源管理器投票,以及告诉资源管理器提交或终止事务。
以下图所示,该应用程序为一个非事务性客户端调用机器A上的服务。机器A上的服务被配置来使用一个事务。这个服务会成为事务的根(root),它不只能够启动事务,也能够决定何时结束事务。
WCF中每一个事务只多有一个根服务,这是由于非事务性客户端也能够做为服务的根。
当机器A事务中的某个服务尝试访问机器B中的资源或服务时,他应该有一个远程服务的代理,这个代理能够传播事务ID到机器B。机器B的拦截器能够获取事务ID,而后通知机器B上的DTC来启动并管理本地事务。由于事务ID已经传播给机器B,因此机器B上的资源管理器能够自动加载这个事务ID。与之相似,事务ID也会传播到机器C。
当事务完成时,若是全部的参与者投票提交事务,此时就会启动两阶段提交协议。根机器上的DTC会收集全部的投票,并通知参与事务的全部机器上的DTC,告诉它们启动第一阶段协议。远程机器上的DTC收集本身机器上全部资源管理器的投票结果并告诉DTC。在全部远程机器都返回结果之后,根机器上的DTC综合全部资源管理器的投票结果。若是全部的资源管理器都投票提交,根机器上的DTC会通知远程上的全部的DTC来启动第二阶段协议,而后通知各个资源管理器提交事务。若是一个资源管理器投票终止事务,那么根机器上的DTC就会通知全部的DTC终止事务。注意,只有根事务上的DTC才有权利收集投票结果并作出决策。
.NET能够动态地给事务管理器分配事务。若是事务管理器没法胜任工做,.NET将会提高事务,也就是让更高级别的事务管理器来管理事务。一个事务能够被提高多个一旦提高就没法降级。由于能够动态提高,因此开发人员避免了直接与事务管理器打交道。
LTM提高
.NET里的每一个事务都是有LTM着手管理的。只有事务只与单个持久化资源交互,并且事务不尝试传播事务到WCF服务,LTM就能代码最佳的性能。LTM还能够管理易失型资源管理器,可是,若是事务尝试加入第二个持久化资源或者传播事务给其它服务,.NET将会从LTM提高到DTC。若是第一个持久化事务被KTM访问,.NET将会把事务从LTM提高到KTM。
KTM提高
只要与单个内核资源管理器(LRM)交互且事务是本地的,KTM就能够管理事务。KTM能够在须要时管理尽量多的易失型资源管理器。若是事务尝试加入第二个持久化资源或者传播事务给其它服务,.NET将会从KTM提高到DTC。