2010年11月11日星期四

TransactionScope简介

TransactionScope是.net2.0开始提供的事务处理机制中的关键。
Java2EE中有分散业务的Transaction管理,所以.net中也应该有。

TransactionScope能够实现的功能,简单的说其实就是分散业务的统合管理,
不再仅仅是一个DBConnection中的一连处理,可以像Java2EE一样管理所有的业务,
比如对多个数据库的操作,只要在TransactionScope内,就全受其所管。
而且,TransactionScope还可以嵌套,设定范围。

对于涉及Transaction的Aplication, MS推荐使用黯然型的TransactionScope,
即,具体的业务逻辑不需要关注什么时候BeginTransaction,什么时候Commit,或者Rollback,
只要将一堆事情,当成一件事做完就可以了。

具体例:
void btnImplicitDistributed_Click(object sender, EventArgs e)
{
    // Create the TransactionScope
    using (TransactionScope oTranScope = new TransactionScope(TransactionScopeOptions.Required))
    {
        // first job
        using (IConnection oCn1 = new SqlConnection(this.constr1))
        {
            ICommand oCmd1 = new SqlCommand(this.sSQL, oCn1);
            oCn1.Open();
            // At this point, the connection is in the transaction scope,
            // which is a lightweight transaction.
            oCmd1.ExecuteNonQuery();
            oCn1.Close();
        }
        // second job
        using (IConnection oCn2 = new OracleConnection(this.constr2))
        {
            ICommand oCmd2 = new OracleCommand(this.sSQL, oCn2);
            oCn2.Open();
            // The connection is enlisted in the transaction scope,
            // which is now promoted to a distributed transaction
            // controlled by MSDTC
            oCmd2.ExecuteNonQuery();
            oCn2.Close();
        }
        // Tell the transaction scope to commit when ready
        oTranScope.Consistent = true;
        // The following bracket completes and disposes the transaction
        // or do this.
        // oTranScope.Complete();
    }
}

上例中,各自DBTransaction会隐式的加入到TransactionScope中,正常处理结束后,在跳出using之后,就会判断TransactionScope的Commitable属性,决定是否执行Commit;中途出现Exception的话,自动调用Scope中保存的各个Tranasction的Rollback.

上例的两个DB操作,通常会放到两个Method中调用,或反射调用,甚至在一个LIST中遍历调用。只要是在这个Scope内,就算是一个大的Transaction。

TransactionScopeOptions范围限定简介:
TransactionScopeOptionsDescription
Required(default)If within a currently active transaction scope, this transaction scope will join it. Otherwise it will create its own transaction scope.
RequiresNewThis transaction will create its own transaction scope.
SuppressNo transaction.


嵌套
using(TransactionScope scope1 = new TransactionScope())
{
     try
     {
          //Start of non-transactional section 
          using(TransactionScope scope2 = new
             TransactionScope(TransactionScopeOption.Suppress))
          {
               //Do non-transactional work here
          }
          //Restores ambient transaction here
   }
     catch
     {}
   //Rest of scope1
}

没有评论: