基于WS-AtomicTransaction标准的WCF远程分布式事务(一)
2007-05-26 23:08
330 查看
在.net remoting的事务传播以及wcf分布式事务 中,我们用TIP协在.net remoting协议上实现了远程事务,其本质是通过将TIP事务的TIP URL传递到远程机器上,然后由远程机器通过TIP协议连接到事务协调器上,但是总体看下来还是有一些缺点:
(1)实现起来还是有点麻烦。
(2)特别是如果涉及多台服务器,多个服务都参与到事务中的时候,那样需要将TIP URL传来传去,换言之,需要自己实现事务传播,那更是麻烦。
(3)不支持异构系统,比如除了调用.net remoting外,还需要调用j2ee的web service的话,那根本就不可能做到AtomicTransaction了。
相对而言,WCF在远程分布式事务传播上就简单得多了,而且远程分布式事务传播是WCF内部实现的,使用起来只需要在配置文件上和Contract上面加上一些特性即可。与TIP事务不同,WCF是通过实现WS-Transaction,WS-Coordination, WS-AtomicTransaction,而这几个都不是微软自己的协议,是一套工业标准。只要服务方的基础架构也实现了这套工业标准,WCF实现的WS就可以和WebSphere实现的WS在实现分布式事务。
废话少说,我们就来看看怎么用WCF实现基于WS-AT的远程分布式事务吧(假设有两台服务器MachineA和MachineB参与了分布式事务)。
第一件要做的事情就是配置MSDTC,让它只是WS-AT协议
1、安装Windows Communication Foundation 更新程序 (KB912817)
2、使用Windows SDKs的工具MakeCert.exe,为MachineA和MachineB生成X.509证书(分别称为CertA和CertB)
MakeCert.exe -r -pe -sky exchange -n "CN=MachineA" -ss Root -sr LocalMachine
MakeCert.exe -r -pe -sky exchange -n "CN=MachineB" -ss Root -sr LocalMachine
这里需要注意的是"CN=MachineA"中的服务器名,需要用FQDN,比如MachineA在域cos.com,那么就需要用"CN=MachineA.cos.com",而不是MachineA。
3、在MachineA中,从证书中的计算机帐号Trusted Root Certificate Authority Node区到处证书CertA,并导入到Personal 区域(导出时需要同时导出私钥)。在MachineB也做同样的操作。
[ServiceContract()]
public interface ICustomerService
public class CustomerService : ICustomerService
<system.serviceModel>
<diagnostics>
<messageLogging logEntireMessage="true" logMalformedMessages="true" logMessagesAtServiceLevel="true" logMessagesAtTransportLevel="true" />
</diagnostics>
<behaviors />
<bindings>
<customBinding>
<binding name="httpWSAT">
<transactionFlow transactionProtocol="WSAtomicTransactionOctober2004" />
<httpTransport />
</binding>
</customBinding>
<netTcpBinding>
<binding name="netTCPWSAT" transactionFlow="true" transactionProtocol="OleTransactions" />
</netTcpBinding>
<wsHttpBinding>
<binding name="wsTransaction" transactionFlow="true">
<security mode="None" />
</binding>
</wsHttpBinding>
</bindings>
<client>
<endpoint address="http://li/CustomerService" binding="customBinding"
bindingConfiguration="httpWSAT" contract="ICustomerService" name="ICustomerService">
<identity>
<userPrincipalName value="domain\username" />
</identity>
</endpoint>
<endpoint address="http://li/OrderService" binding="customBinding"
bindingConfiguration="httpWSAT" contract="WCFTransactionClient.OrderService.IOrderService"
name="IOrderService">
<identity>
<userPrincipalName value="domain\username" />
</identity>
</endpoint>
</client>
</system.serviceModel>
服务器端配置:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<diagnostics performanceCounters="Off" />
<behaviors>
<serviceBehaviors>
<behavior name="metadataSupport">
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="false" />
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>
<customBinding>
<binding name="httpWSATBinding">
<transactionFlow transactionProtocol="WSAtomicTransactionOctober2004" />
<httpTransport/>
</binding>
</customBinding>
<netTcpBinding>
<binding name="netTCPWSATBinding" transactionFlow="true" transactionProtocol="WSAtomicTransactionOctober2004" />
</netTcpBinding>
<wsHttpBinding>
<binding name="wsTransaction" transactionFlow="true">
<security mode="None" />
</binding>
</wsHttpBinding>
</bindings>
<services>
<service behaviorConfiguration="metadataSupport" name="WCFTransactionLib.CustomerService">
<endpoint address="" binding="customBinding" bindingConfiguration="httpWSATBinding"
contract="WCFTransactionLib.ICustomerService" />
<host>
<baseAddresses>
<add baseAddress="http://li/CustomerService" />
</baseAddresses>
</host>
</service>
<service behaviorConfiguration="metadataSupport" name="WCFTransactionLib.OrderService">
<endpoint address="" binding="customBinding" bindingConfiguration="httpWSATBinding"
contract="WCFTransactionLib.IOrderService" />
<host>
<baseAddresses>
<add baseAddress="http://li/OrderService" />
</baseAddresses>
</host>
</service>
</services>
</system.serviceModel>
</configuration>
配置文件里面有一点需要注意的,就是在endpoint address和baseAddress中使用的地址中的服务器地址必须使用和生成X.509证书一样的地址,比如必须用http://MachineA.cos.com,而不是http://192.168.1.101或者http://MachineA。这个是ssl证书的要求:)
废话少说了,先附上测试用的源代码吧
/Files/walkinhill/wcftransactiondemosolutionnew.zip
已经写了不少了,只好把通过分析WCF程序之间交互的消息来看看WS-AT的原理的。只好留作下一篇在写WS-AT消息的内容和WS-AT和OleTx协议的一些差别了:)
参考资料:
http://msdn2.microsoft.com/en-us/library/ms733943.aspx
(1)实现起来还是有点麻烦。
(2)特别是如果涉及多台服务器,多个服务都参与到事务中的时候,那样需要将TIP URL传来传去,换言之,需要自己实现事务传播,那更是麻烦。
(3)不支持异构系统,比如除了调用.net remoting外,还需要调用j2ee的web service的话,那根本就不可能做到AtomicTransaction了。
相对而言,WCF在远程分布式事务传播上就简单得多了,而且远程分布式事务传播是WCF内部实现的,使用起来只需要在配置文件上和Contract上面加上一些特性即可。与TIP事务不同,WCF是通过实现WS-Transaction,WS-Coordination, WS-AtomicTransaction,而这几个都不是微软自己的协议,是一套工业标准。只要服务方的基础架构也实现了这套工业标准,WCF实现的WS就可以和WebSphere实现的WS在实现分布式事务。
废话少说,我们就来看看怎么用WCF实现基于WS-AT的远程分布式事务吧(假设有两台服务器MachineA和MachineB参与了分布式事务)。
第一件要做的事情就是配置MSDTC,让它只是WS-AT协议
1、安装Windows Communication Foundation 更新程序 (KB912817)
2、使用Windows SDKs的工具MakeCert.exe,为MachineA和MachineB生成X.509证书(分别称为CertA和CertB)
MakeCert.exe -r -pe -sky exchange -n "CN=MachineA" -ss Root -sr LocalMachine
MakeCert.exe -r -pe -sky exchange -n "CN=MachineB" -ss Root -sr LocalMachine
这里需要注意的是"CN=MachineA"中的服务器名,需要用FQDN,比如MachineA在域cos.com,那么就需要用"CN=MachineA.cos.com",而不是MachineA。
3、在MachineA中,从证书中的计算机帐号Trusted Root Certificate Authority Node区到处证书CertA,并导入到Personal 区域(导出时需要同时导出私钥)。在MachineB也做同样的操作。
[ServiceContract()]
public interface ICustomerService
public class CustomerService : ICustomerService
<system.serviceModel>
<diagnostics>
<messageLogging logEntireMessage="true" logMalformedMessages="true" logMessagesAtServiceLevel="true" logMessagesAtTransportLevel="true" />
</diagnostics>
<behaviors />
<bindings>
<customBinding>
<binding name="httpWSAT">
<transactionFlow transactionProtocol="WSAtomicTransactionOctober2004" />
<httpTransport />
</binding>
</customBinding>
<netTcpBinding>
<binding name="netTCPWSAT" transactionFlow="true" transactionProtocol="OleTransactions" />
</netTcpBinding>
<wsHttpBinding>
<binding name="wsTransaction" transactionFlow="true">
<security mode="None" />
</binding>
</wsHttpBinding>
</bindings>
<client>
<endpoint address="http://li/CustomerService" binding="customBinding"
bindingConfiguration="httpWSAT" contract="ICustomerService" name="ICustomerService">
<identity>
<userPrincipalName value="domain\username" />
</identity>
</endpoint>
<endpoint address="http://li/OrderService" binding="customBinding"
bindingConfiguration="httpWSAT" contract="WCFTransactionClient.OrderService.IOrderService"
name="IOrderService">
<identity>
<userPrincipalName value="domain\username" />
</identity>
</endpoint>
</client>
</system.serviceModel>
服务器端配置:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<diagnostics performanceCounters="Off" />
<behaviors>
<serviceBehaviors>
<behavior name="metadataSupport">
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="false" />
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>
<customBinding>
<binding name="httpWSATBinding">
<transactionFlow transactionProtocol="WSAtomicTransactionOctober2004" />
<httpTransport/>
</binding>
</customBinding>
<netTcpBinding>
<binding name="netTCPWSATBinding" transactionFlow="true" transactionProtocol="WSAtomicTransactionOctober2004" />
</netTcpBinding>
<wsHttpBinding>
<binding name="wsTransaction" transactionFlow="true">
<security mode="None" />
</binding>
</wsHttpBinding>
</bindings>
<services>
<service behaviorConfiguration="metadataSupport" name="WCFTransactionLib.CustomerService">
<endpoint address="" binding="customBinding" bindingConfiguration="httpWSATBinding"
contract="WCFTransactionLib.ICustomerService" />
<host>
<baseAddresses>
<add baseAddress="http://li/CustomerService" />
</baseAddresses>
</host>
</service>
<service behaviorConfiguration="metadataSupport" name="WCFTransactionLib.OrderService">
<endpoint address="" binding="customBinding" bindingConfiguration="httpWSATBinding"
contract="WCFTransactionLib.IOrderService" />
<host>
<baseAddresses>
<add baseAddress="http://li/OrderService" />
</baseAddresses>
</host>
</service>
</services>
</system.serviceModel>
</configuration>
配置文件里面有一点需要注意的,就是在endpoint address和baseAddress中使用的地址中的服务器地址必须使用和生成X.509证书一样的地址,比如必须用http://MachineA.cos.com,而不是http://192.168.1.101或者http://MachineA。这个是ssl证书的要求:)
废话少说了,先附上测试用的源代码吧
/Files/walkinhill/wcftransactiondemosolutionnew.zip
已经写了不少了,只好把通过分析WCF程序之间交互的消息来看看WS-AT的原理的。只好留作下一篇在写WS-AT消息的内容和WS-AT和OleTx协议的一些差别了:)
参考资料:
http://msdn2.microsoft.com/en-us/library/ms733943.aspx
相关文章推荐
- 基于WS-AtomicTransaction标准的WCF远程分布式事务(二)
- 基于WS-AtomicTransaction标准的WCF远程分布式事务(补充)
- 分布式事务之——tcc-transaction分布式TCC型事务框架搭建与实战案例(基于Dubbo/Dubbox)
- 基于SpringCloud的分布式事务框架(LCN)
- WCF分布式安全开发实践(8):消息安全模式之用户名身份验证:Message_UserName_WSHttpBinding
- WCF分布式安全开发实践(11):消息安全模式之Certificate身份验证:Message_Certificate_WSHttpBinding
- 小测试,WCF分布式事务的用法以及回滚条件 .
- 架构设计实践:基于WCF大型分布式系统
- 基于WCF大型分布式系统的架构设计
- 基于MySQL的分布式事务控制方案(C#实现)
- 基于可靠消息的分布式事务错误处理
- 从远程服务器数据库中同步数据到本地数据库 sql server 2008 开启分布式事务
- 分布式事务、基于Best Efforts 1PC模式的事务
- 分布式事务之——tcc-transaction分布式TCC型事务框架搭建与实战案例(基于Dubbo/Dubbox)
- wcf 分布式事务实践
- WCF分布式安全开发实践(11):消息安全模式之Certificate身份验证:Message_Certificate_WSHttpBinding
- WCF分布式安全开发实践(12):消息安全模式之自定义X509证书验证:Message_CustomX509Certificate_WSHttpBinding
- 谈谈分布式事务之二:基于DTC的分布式事务管理模型[上篇]
- 采用Best effort 1pc + 回滚补偿机制实现的一个distributed transaction (分布式事务框架).基于dubbo rpc服务上实现。
- 分布式事务五_基于可靠消息的最终一致性_异常流程