中国IT动力,最新最全的IT技术教程
最新100篇 | 推荐100篇 | 专题100篇 | 排行榜 | 搜索 | 在线API文档 | 网通镜像
首 页 | 程序开发 | 操作系统 | 软件应用 | 图形图象 | 网络应用 | 精文荟萃 | 教育认证 | 硬件维护 | 未整理篇 | 站长教程
ASP JS PHP工程 ASP.NET 网站建设 UML J2EESUN .NET VC VB VFP 网络维护 数据库 DB2 SQL2000 Oracle Mysql
服务器 Win2000 Office C DreamWeaver FireWorks Flash PhotoShop 上网宝典 CorelDraw 协议大全 网络安全 微软认证
硬件维护  CPU  主板  硬盘  内存  显卡  显示器  键盘鼠标  声卡音箱  打印机  机箱电源  BIOS  网卡  C#  Java  Delphi  vs.net2005
  当前位置:> 程序开发 > 编程语言 > .NET > 临时文章
Using distributed transactions in .Net 1.x without deriving from ServicedComponent
作者:未知 时间:2005-07-27 21:29 出处:CSDN 责编:chinaitpower
              摘要:Using distributed transactions in .Net 1.x without deriving from ServicedComponent

引用 : http://blogs.msdn.com/florinlazar/archive/2004/07/24/194199.aspx

The most used feature of System.EnterpriseServices or COM+ is the distributed transaction support. And the automatic transaction programming model in ES using attributes ([Transaction] and [AutoComplete]) is great and nice but (it is always a but!)... you need to inherit from ServicedComponent and the Transaction attribute is only available at class level, and you need to register your component in the COM+ repository and the list can continue.

 

If doing this seems overkill to you, because all you need is a distributed transaction to protect your code/actions and you don't care of any of the others ES features (which are great ones nevertheless) then there is a solution for you: System.EnterpriseServices.ServiceDomain. Here is some sample code:

 

using System;

using System.EnterpriseServices;

 

namespace SDSample

{

   class Class1

   {

      [MTAThread]      

      static void Main(string[] args)

      {

         ServiceConfig config = new ServiceConfig();

         config.Transaction = TransactionOption.Required;

         ServiceDomain.Enter(config);

         try

         {

            MyTxCode();

         }

         catch(Exception e)

         {

            // we got an exception

            Console.WriteLine(e.Message);

            // so, we should abort the transaction

            ContextUtil.SetAbort();

         }

         finally

         {

            ServiceDomain.Leave();

         }

      }

 

      // The code that I want to be transactional

      static void MyTxCode()

      {

         Console.WriteLine(ContextUtil.TransactionId);

                 

         // Open connection to database 1

         // Execute update in database 1

 

         // Open connection to database 2

         // Execute update in database 2

      }

   }

}

 

Of course, you can go further and create a helper class, let’s call it ESTransactionScope (similar to System.Transactions.TransactionScope that will arrive in Whidbey) that will be very easy to use:

 

using System;

using System.EnterpriseServices;

 

namespace SDSample2

{

   class Class1

   {

      [MTAThread]      

      static void Main(string[] args)

      {

         using( ESTransactionScope ts = new ESTransactionScope())

         {

           MyTxCode();

 

           // Everything went well, no exception thrown

           // so let’s vote for Commit

           ts.Complete();

         }

      }

 

      static void MyTxCode()

      {

         Console.WriteLine(ContextUtil.TransactionId);

                 

         // Open connection to database 1

         // Execute update in database 1

 

         // Open connection to database 2

         // Execute update in database 2             

      }

   }

 

   // Used to create transactional code blocks

   class ESTransactionScope : IDisposable

   {

      // Dispose must be called to exit the transactional block

      public void Dispose()

      {                

         if(!this.Consistent)

         {

            ContextUtil.SetAbort();

         }

         ServiceDomain.Leave();

      }

 

      // by calling this method, you mark the scope as being consistent

      // and ready to for commit

      // if the method is never called, upon dispose, the scope will abort the transaction 

      public void Complete()

      {

         this.Consistent = true;

      }   

 

      public ESTransactionScope()

      {                

         EnterTxContext(TransactionOption.Required);

      }

 

      public ESTransactionScope(TransactionOption txOption)

      {

         EnterTxContext(txOption);

      }

 

      private void EnterTxContext(TransactionOption txOption)

      {

         ServiceConfig config = new ServiceConfig();

         config.Transaction = txOption;

         ServiceDomain.Enter(config);          

      }

 

      // By default, the scope is inconsistent;

      // To Commit the transaction on exit, the Consistent flag

      // must be set to true before Dispose is called

      private bool Consistent = false;

   }

}

 

System.EnterpriseServices.ServiceDomain is available only on XP SP2 (or higher) and Windows Server 2003 and only in .Net 1.1.

 

If you need your app to work with .Net 1.0 or on Windows 2000 or XP pre-SP2, you can use the trick that Don Box posted at http://www.gotdotnet.com/team/dbox/default.aspx?key=2004-07-12T08:40:44Z  It uses exactly one transactional ServicedComponent based class and a DoCallback method to which you pass the delegate to your MyTxCode function that needs to execute in a transaction.


关闭本页
 
首页 | 投资与合作 | 服务条款 | 隐私政策 | 收藏本站 | 设为首页 | 新用户注册 | 免责声明 | 使用帮助
Copyright ©2005-2008 chinaitpower.com All rights reserved. www.chinaitpower.com 版权所有