惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

酷 壳 – CoolShell
酷 壳 – CoolShell
H
Hacker News: Front Page
P
Palo Alto Networks Blog
T
ThreatConnect
Apple Machine Learning Research
Apple Machine Learning Research
博客园_首页
T
True Tiger Recordings
P
Privacy & Cybersecurity Law Blog
B
Blog
IT之家
IT之家
Last Week in AI
Last Week in AI
F
Full Disclosure
Hacker News: Ask HN
Hacker News: Ask HN
C
Comments on: Blog
Microsoft Azure Blog
Microsoft Azure Blog
C
Cybersecurity and Infrastructure Security Agency CISA
Microsoft Security Blog
Microsoft Security Blog
博客园 - 【当耐特】
N
News and Events Feed by Topic
NISL@THU
NISL@THU
腾讯CDC
雷峰网
雷峰网
Security Latest
Security Latest
李成银的技术随笔
M
Microsoft Research Blog - Microsoft Research
L
LangChain Blog
L
Lohrmann on Cybersecurity
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
C
Check Point Blog
Y
Y Combinator Blog
Recent Announcements
Recent Announcements
博客园 - Franky
N
News | PayPal Newsroom
V
V2EX
A
About on SuperTechFans
The Register - Security
The Register - Security
月光博客
月光博客
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Google Online Security Blog
Google Online Security Blog
MyScale Blog
MyScale Blog
Cisco Talos Blog
Cisco Talos Blog
Vercel News
Vercel News
WordPress大学
WordPress大学
C
Cyber Attacks, Cyber Crime and Cyber Security
The Hacker News
The Hacker News
IntelliJ IDEA : IntelliJ IDEA – the Leading IDE for Professional Development in Java and Kotlin | The JetBrains Blog
IntelliJ IDEA : IntelliJ IDEA – the Leading IDE for Professional Development in Java and Kotlin | The JetBrains Blog
爱范儿
爱范儿
A
Arctic Wolf
L
LINUX DO - 最新话题
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More

博客园 - Kevin Li

使用WMI远程部署/更新BizTalk程序集 基于WS-AtomicTransaction标准的WCF远程分布式事务(补充) 基于WS-AtomicTransaction标准的WCF远程分布式事务(二) 在Jeffrey Zhao的基础上+反编译System.Web.Extensions.Design得到的完整Ajax代码 .net remoting的事务传播以及wcf分布式事务 在多线程环境下使用HttpWebRequest或者调用Web Service 一篇介绍.NET 2.0 范型挺全面的文章 C# 2.0中的范型和Nullable范型 Windows 2003 下分布式事务协调器(DTC)的配置 使用SQLSourceSafe控制数据库的版本 MySql 主键(自动增加)的数据类型所带来的错误 使用TraceListener 自动保存跟踪信息到文件中 接口属性集成与智能提示的奇怪问题 动态创建程序集中的类 动态创建程序集中的类 使用NUnit测试包含应用程序配置的dll文件 解决“COM+ 无法与 Microsoft 分布式事务协调程序交谈”的问题 [导入]一些很有用的Reflector 插件 Web安全性原则
基于WS-AtomicTransaction标准的WCF远程分布式事务(一)
Kevin Li · 2007-05-26 · via 博客园 - Kevin Li

.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也做同样的操作。

4、在MachineA将CertA的公钥导出到文件CertA.cer,并导入到MachineB的计算机帐号中的Trusted Root Certificate Authority Node区域和Personal区域。同样将CertB的公钥导出到MachineA的计算机帐号中的Trusted Root Certificate Authority Node区域和Personal区域。
5、配置MSDTC,启用WS-AT协议。
      注册程序集wsatui.dll(可以在Windows SDKs的bin目录找到该文件,默认安装目录是C:\Program Files\Microsoft SDKs\Windows\v6.0\Bin),执行命令:
      regasm /codebase C:\Program Files\Microsoft SDKs\Windows\v6.0\Bin\wsatui.dll
6、执行了上面的操作後,打开MSDTC的配置,就会看到多了一个WS-AT的Tab。在里面配置一下相关的参数:
         (1)选择启用WS-AT
         (2)设置Https端口,默认是443,但为了避免冲突,我设成了1443
         (3)设置Endpoint Certificate,对于MachineA,选择CertA,对于MachineB,选择CertB
         (4)设置Authorized certificates,对于MachineA,选择CertB,对于MachineA,选择CertA(如果有多台服务器参与分布式事务,可以选择多个cert) 
    

到此为止已经配置好启用WS-AT协议了,接下来就可以写WCF程序来跑跑WS-AT协议了。

第二步:写WCF程序
和一般的WCF程序差不多,唯一的区别就是配置上有所不同,和需要在Contract的方法上面加一些特性。对于接口方法,加上特性:[TransactionFlow(TransactionFlowOption.Mandatory)]。对于实现类,加上特性:[OperationBehavior(TransactionScopeRequired=true)]


    [ServiceContract()]
    
public interface ICustomerService
    
{
        [OperationContract]
        [TransactionFlow(TransactionFlowOption.Mandatory)]
        
int Update(int customerID);

        [OperationContract]
        
string GetCustomerName(int customerID);
        
    }


public class CustomerService : ICustomerService
    
{
        [OperationBehavior(TransactionScopeRequired
=true)]
        
public int Update(int customerID)
        
{
            
try
            
{
                Console.WriteLine(
"Update Customer");
                
using (SqlConnection cn = new SqlConnection("Server=.;Integrated security=true;initial catalog=learningsite"))
                
{
                    cn.Open();
                    SqlCommand cmd 
= new SqlCommand("Update Customers Set CustomerName=CustomerName + Cast(@CustomerID as varchar(10)) where customerID = @customerID", cn);
                    cmd.Parameters.AddWithValue(
"@CustomerID", customerID);
                    
return cmd.ExecuteNonQuery() > 0 ? 0 : -1;
                }

            }

            
catch (Exception ex)
            
{
                Console.WriteLine(ex.ToString());
                
return -1;
            }
            
        }

                
        
public string GetCustomerName(int customerID)
        
{
            
string now = DateTime.Now.ToString();
            Console.WriteLine(
"CustomerName");
            
return "CustomerName";
        }

    }


    
<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>