.net中的交易

在C#.Net 2.0中执行事务的最佳实践是什么? 什么是应该使用的类? 有什么陷阱要留意等所有提交和回滚的东西。 我刚刚开始一个项目,在将数据插入数据库时​​可能需要执行一些事务。 任何有关交易的基本内容的反应或链接都是受欢迎的。


主要有两种交易; 连接交易和环境交易。 连接事务(如SqlTransaction)直接绑定到数据库连接(例如SqlConnection),这意味着您必须保持传递连接 - 在某些情况下可以,但不允许“创建/使用/释放”用法,并且不允许跨数据库工作。 一个例子(格式化为空格):

using (IDbTransaction tran = conn.BeginTransaction()) {
    try {
        // your code
        tran.Commit();
    }  catch {
        tran.Rollback();
        throw;
    }
}

不是太乱,但仅限于我们的连接“conn”。 如果我们想要调用不同的方法,我们现在需要传递“conn”。

另一种选择是环境交易; .NET 2.0中的新特性,TransactionScope对象(System.Transactions.dll)允许在一系列操作中使用(合适的提供者将自动登录环境事务)。 这可以很容易地适应现有的(非事务性)代码,并且可以与多个提供商交谈(尽管如果您与多个提供商交谈,DTC将会参与其中)。

例如:

using(TransactionScope tran = new TransactionScope()) {
    CallAMethodThatDoesSomeWork();
    CallAMethodThatDoesSomeMoreWork();
    tran.Complete();
}

这里请注意,这两种方法可以处理他们自己的连接(open / use / close / dispose),但是他们会默默地成为环境事务的一部分,而不需要我们传递任何东西。

如果你的代码错误,Dispose()将在没有Complete()的情况下被调用,所以它会被回滚。 预期的嵌套等被支持,虽然你不能回滚一个内部交易,但完成外部交易:如果有人不满意,交易将被中止。

TransactionScope的另一个优点是它不仅仅与数据库绑定。 任何支持事务的提供者都可以使用它。 例如WCF。 或者甚至有一些与TransactionScope兼容的对象模型(即具有回滚功能的.NET类 - 也许比纪念更容易,尽管我自己从未使用过这种方法)。

总而言之,这是一个非常非常有用的对象。

一些注意事项:

  • 在SQL Server 2000上,TransactionScope将立即转到DTC; 这在SQL Server 2005及更高版本中得到了解决,它可以使用LTM(开销少得多),直到与2个源等进行通信时,它被提升为DTC。
  • 有一个小故障,这意味着你可能需要调整你的连接字符串

  • protected void Button1_Click(object sender, EventArgs e)
       {
    
    
           using (SqlConnection connection1 = new SqlConnection("Data Source=.SQLEXPRESS;AttachDbFilename=|DataDirectory|Database.mdf;Integrated Security=True;User Instance=True"))
           {
               connection1.Open();
    
               // Start a local transaction.
               SqlTransaction sqlTran = connection1.BeginTransaction();
    
               // Enlist a command in the current transaction.
               SqlCommand command = connection1.CreateCommand();
               command.Transaction = sqlTran;
    
               try
               {
                   // Execute two separate commands.
                   command.CommandText =
                    "insert into [doctor](drname,drspecialization,drday) values ('a','b','c')";
                   command.ExecuteNonQuery();
                   command.CommandText =
                    "insert into [doctor](drname,drspecialization,drday) values ('x','y','z')";
                   command.ExecuteNonQuery();
    
                   // Commit the transaction.
                   sqlTran.Commit();
                   Label3.Text = "Both records were written to database.";
               }
               catch (Exception ex)
               {
                   // Handle the exception if the transaction fails to commit.
                   Label4.Text = ex.Message;
    
    
                   try
                   {
                       // Attempt to roll back the transaction.
                       sqlTran.Rollback();
                   }
                   catch (Exception exRollback)
                   {
                       // Throws an InvalidOperationException if the connection 
                       // is closed or the transaction has already been rolled 
                       // back on the server.
                       Label5.Text = exRollback.Message;
    
                   }
               }
           }
    
    
       }
    

    您也可以将事务包装到自己的存储过程中,并以此方式处理它,而不是在C#中进行事务处理。

    链接地址: http://www.djcxy.com/p/49973.html

    上一篇: Transactions in .net

    下一篇: Nested/Child TransactionScope Rollback