翔如菲菲

其实天很蓝,阴云总会散;其实海不宽,此岸连彼岸.

导航

.NET2.0 事务处理

在 .NET Framework 2.0中增加了System.Transactions,这是一种新的命名空间,完全专注于控制事务性行为。引入了执行事务性工作的更简单方法及一些新的 性能优化。System.Transactions提供了一个“轻量级”的、易于使用的Transaction框架。

下面介绍System.Transactions的几种用法。

首先要引用:using System.Transactions;。

其次,将事务操作代码放在TransactionScope中执行。如:

using (TransactionScope ts = new TransactionScope())

{

    //事务操作代码

    ts.Complete();

}

这是最简单,也是最常见的用法。创建了新的 TransactionScope 对象后,即开始创建事务范围。如代码示例所示,建议使用 using 语句创建范围。位于 using 块内的所有操作将成为一个事务的一部分,因为它们共享其所定义的事务执行上下文。本例中的最后一行,调用 TransactionScope 的 Complete 方法,将导致退出该块时请求提交该事务。此方法还提供了内置的错误处理,出现异常时会终止事务。                                

using (TransactionScope ts = new TransactionScope())//使整个代码块成为事务性代码

{

    #region 在这里编写需要具备Transaction的代码

    string msg = "";

    string conString = "data source=127.0.0.1;database=codematic;user id=sa;

password=";

    SqlConnection myConnection = new SqlConnection(conString);

    myConnection.Open();

    SqlCommand myCommand = new SqlCommand();

    myCommand.Connection = myConnection;

    try

    {

        myCommand.CommandText = "update P_Product set Name='电脑2' where Id=52";

        myCommand.ExecuteNonQuery();

        myCommand.CommandText = "update P_Product set Name='电脑3' where Id=53";

        myCommand.ExecuteNonQuery();

        msg = "成功!";

    }

    catch (Exception ex)

    {

        msg = "失败:" + ex.Message;

    }

    finally

    {

        myConnection.Close();

    }

    #endregion

    ts.Complete();

    return msg;              

}           

上面的代码 演示了在一个Transaction Scope里面打开一个数据库连接的过程。这个数据库连接由于处在一个Transaction Scope里面,所以会自动获得Transaction的能力。如果这里数据库连接的是SQL Server 2005,那么这个Transaction将不会激活一个MSDTC管理的分布式事务,而是会由.NET创建一个Local Transaction,性能非常高。但是如果是SQL Server 2000,则会自动激活一个分布式事务,在性能上会受一定的损失。

再看下面的例子:

void MethodMoreConn()

{

    using (TransactionScope ts = new TransactionScope())

    {

        using (SqlConnection conn = new SqlConnection(conString1))

        {

            conn.Open();

            using (SqlConnection conn2 = new SqlConnection(conString2))

            {

                conn2.Open();

            }

        }

        ts.Complete();

    }

}

这个例子更 加充分地说明了Transaction Scope的强大,两个数据库连接!虽然上面的conn和conn2是两个不同的连接对象,可能分别连接到不同的数据库,但是由于它们处在一个 TransactionScope中,它们就具备了“联动”的Transaction能力。在这里,将自动激活一个MSDTC管理的分布式事务(可以通过 打开【管理工具】里面的组件服务,来查看当前的分布式事务列表)。

1.在分布式事务中登记

ADO.NET 2.0 中的新增功能支持使用 EnlistTransaction 方法在分布式事务中登记。由于 EnlistTransaction 在 Transaction 实例中登记连接,因此,该方法利用 System.Transactions 命名空间中的可用功能来管理分布式事务,从而比使用 System.EnterpriseServices. ITransaction 对象的 EnlistDistributedTransaction 更可取。此外,其语义也稍有不同:在一个事务中显式登记了某个连接后,如果第一个事务尚未完成,则无法取消登记或在另一个事务中登记该连接。

void MethodEnlist()

{

    CommittableTransaction tx = new CommittableTransaction();

    using (SqlConnection conn = new SqlConnection(conString))

    {

        conn.EnlistTransaction(tx);

    }

    tx.Commit();

}

2.实现嵌套事务范围

void RootMethod()

{

    using (TransactionScope scope = new TransactionScope())

    {

        //操作代码

        SonMethod();//子事务方法

        scope.Complete();

    }

}

void SonMethod()

{

    using (TransactionScope scope = new TransactionScope())

    {

        //操作代码

        scope.Complete();

    }

}

3.事务范围附加选项

如果 你想要保留代码部分执行的操作,并且在操作失败的情况下不希望中止环境事务,则Suppress对你很有帮助。例如,在你想要执行日志记录或审核操作时, 不管你的环境事务是提交还是中止,上述值都很有用。该值允许你在事务范围内具有非事务性的代码部分,如以下示例所示。

void MethodSuppress()

{

    using (TransactionScope scope1 = new TransactionScope())//开始事务

    {

        try

        {

            //开始一个非事务范围

            using (TransactionScope scope2 = new TransactionScope(

                 TransactionScopeOption.Suppress))

            {

                //不受事务控制代码

            }

            //从这里开始又回归事务处理

        }

        catch

        { }       

    }

}

posted on 2009-06-23 09:10  翔如飞飞  阅读(223)  评论(0编辑  收藏  举报