zoukankan      html  css  js  c++  java
  • .net remoting的事务传播以及wcf分布式事务

    在.net 1.1或者.net 2.0中要实现分布式事务,如果不涉及远程调用,如调用remoting或者web service的方法,应该说是一件非常简单的事情,只需要用COM+(1.1/ServiceDomain)或者TransactionScope(2.0),通过msdtc协调即可。

    但是当事务方法中还需要调用remoting或者web service(不使用ws-at)时,由于remoting不支持事务传播机制,因此即便客户端调用remoting后发生错误回滚,remoting server上已经执行的操作(如数据库操作)也已经无法回滚。

    但是在一些特殊的应用中,数据完整性比性能更重要的情况下,如果希望客户端回滚时,remoting server上执行的操作也可以回滚,那么可以使用msdtc的Transaction Internet Protocol(TIP)协议(事实上,msdtc除了支持常用的OleTx分布式事务协议外,还支持XA和TIP协议),让客户端启动的事务“传播”至Remoting Server,那样只要Remoting Server同样使用客户端传播过来的事务,即可实现Remoting下的分布式事务。具体的做法如下:
    (1)由于TIP事务协议默认是不启用的,所以第一步首先配置MSDTC支持TIP事务。在msdtc属性页中的点击“安全配置”后选中“启用TIP事务”。
    (2)实现ITipTransaction 接口,用于从ContextUtil.Transaction查询TIPTransaction的相关属性。具体是获取TIP事务的TIP URL属性。

    ITipTransaction 接口的定义:
    [ Guid("17CF72D0-BAC5-11d1-B1BF-00C04FC2F3EF") ]
        [ InterfaceType(ComInterfaceType.InterfaceIsIUnknown) ]
        
    public interface ITipTransaction
        
    {
            
    void Push([In, MarshalAs(UnmanagedType.LPStr)] string pszRemoteTmUrl,
                [In, Out, MarshalAs(UnmanagedType.LPStr)] 
    ref string ppszRemoteTxUrl);

            
    void GetTransactionUrl([In, Out, MarshalAs(UnmanagedType.LPStr)] 
                
    ref string ppszLocalTxUrl);
        }
     

    获取TIP URL的代码:
    string url = null
                    
                        ITipTransaction trxn 
    = (ITipTransaction) ContextUtil.Transaction; 
                    
                        trxn.GetTransactionUrl(
    ref url);
                    

    (3)通过一定的机制,将获取得到的TIP URL传递到Remoting服务器。
    要将tip url传递到remoting server方法很多,可以通过参数传递过去,也可以通过callcontext传递过去,具体可以看附件的代码。

    (4)在Remoting Server中,利用TIP URL连接到客户端的事务中,并启动事务。
    获取到client传递过来的tip url后,就可以通过它连接到现有的事务协调器上,具体代码:
    TransactionCallContext ctx = (TransactionCallContext)CallContext.GetData("DTCTxID");
    ServiceConfig config 
    = new ServiceConfig();
                    
                    
    if (ctx != null)
                    
    {
                        config.TipUrl 
    = ctx.TipUrl;
                        config.Transaction 
    = TransactionOption.RequiresNew;
                    }

                    
    else
                    
    {
                        config.Transaction 
    = TransactionOption.Disabled;
                    }

                    
                    
    using(TransactionScope scope = new TransactionScope(config))
                    
    {
                        rows 
    = UpdatePoint();

                        
    if( rows > 0 )
                        
    {
                            scope.SetComplete();
                        }

                    }
    通过上面的方式,就可以实现Remoting下的分布式事务了。

    源代码:
    /Files/walkinhill/RemotingTransactionDemo.rar

    参考文章:
    http://dotnetjunkies.com/WebLog/chris.taylor/articles/54503.aspx
    http://www.codeproject.com/csharp/complus_tip.asp

    尽管通过上面的方式实现了remoting下的分布式事务,但是还是有些麻烦,而且一不小心还是会出错的。相比之下,wcf内部已经实现了这样的事务机制,而且只需要配置一下和外加一些特性就可以实现。而且还支持oletransactions和ws-at协议,看来以后用wcf方便多了。

    最后有一点,这里只是了解了remoting下的分布式事务,但是具体要不要用,还是要充分考虑性能的问题,毕竟远程调用对性能的消耗还是很大的,特别是事务下对资源的锁导致的性能下降更严重:)
  • 相关阅读:
    适配器模式
    事务
    JUnit4
    命令模式
    组合模式
    MySQL语法
    MyEclipse工具
    数据源和连接池
    Annotation
    Java反射机制
  • 原文地址:https://www.cnblogs.com/huqingyu/p/1171633.html
Copyright © 2011-2022 走看看