使用Transaction访问数据库(C#,TransactionScope,.NET 2.0)

针对SQL2005和.NET 2.0的事物机制有了新的突破
传统数据库事物访问机制,代码如下:

 1 public void TransactionTest()
 2         {
 3             string connectionString = "";
 4             IDbConnection connection = new SqlConnection(connectionString);
 5             connection.Open();
 6             IDbCommand command = new SqlCommand();
 7             command.Connection = connection;
 8             IDbTransaction transaction;
 9             transaction = connection.BeginTransaction(); //Enlisting database
10             command.Transaction = transaction;
11             try
12             {
13                 /**//* Interact with database here, then commit the transaction
14                 */
15                 transaction.Commit();
16             }
17             catch
18             {
19                 transaction.Rollback(); //Abort transaction
20             }
21             finally
22             {
23                 connection.Close();
24             }
25         }
26 


或者这种,其实都差不多

 1  using System.Data.SqlClient
   
 2                           DataTable   dt   =   new   DataTable();   
 3                           SqlConnection   cnn   =   new   SqlConnection("连接字符串");  
 4                           SqlCommand   cm   =   new  SqlCommand();  
 5                           cm.Connection   =   cnn;  
 6                           cnn.Open();  
                           //一定要BeginTransaction()
 7
                          SqlTransaction   trans   =   cnn.BeginTransaction(); 

 8                           try  
 9                           {  
10                                   foreach(DataRow   dr   in   dt.Rows)  
11                                   {  
12                                           cm.CommandText   =   "update   [表]   set   [数量]   =   @amount   where   productID   =   @productID";  
13                                           cm.Parameters.Add("@amount",SqlDbType.Int);  
14                                           cm.Parameters["@amount"].Value   =   Convert.ToInt32(dr["amount"]);  
15                                           cm.Parameters.Add("@productID",SqlDbType.VarChar);  
16                                           cm.Parameters["@productID"].Value   =   dr["productID"].ToString();  
17                                           cm.ExecuteNonQuery();  
18                                   }  
19                                   trans.Commit();  
20                           }  
21                           catch  
22                           {  
23                                   trans.Rollback();  
24                           }  
25                           finally  
26                           {  
27                                   cnn.Close();  
28                                   trans.Dispose();  
29                                   cnn.Dispose();  
30                           }  
31                   }


至少需要try catch,

如今使用TransactionScope

1 using(TransactionScope scope = new TransactionScope())
2 {
3 /**//* Perform transactional work here */
4 //No errors - commit transaction
5 scope.Complete();
6 }
7 

一句using中的new,然后scape.complete()就解决了。
TransactionScope是Transaction的精简版,也能很好的完成工作。

另外对嵌套事务和事务的隔离级别也提供了支持

 1 using(TransactionScope scope1 = new TransactionScope())
 2 //Default is Required
 3 {
 4 using(TransactionScope scope2 = new
 5 TransactionScope(TransactionScopeOption.Required))
 6 {}
 7 using(TransactionScope scope3 = new
 8 TransactionScope(TransactionScopeOption.RequiresNew))
 9 {}
10 using(TransactionScope scope4 = new
11 TransactionScope(TransactionScopeOption.Suppress))
12 {}
13 
14 }
15 

下面是对嵌套事务的说明:

嵌套事务的具体请看:http://perhaps.cnblogs.com/archive/2005/08/17/216863.html

需要注意的是:使用transaction时,尽量在其中做必需要的操作,其它和数据库无关的操作就放在transaction外面。毕竟SQL事务处理时,是一种独占的状态。尽快使用完毕释放资源非常重要。

嵌套事务:

   在拜读了idior兄的Transaction in ADO.net 2.0之后,偶也忍不住手痒,写下了关于J2EE Tranaction的几个基本概念一文。在阅读以及总结的过程中,我发现在Transaction的支持上,ADO.net仍需继续努力的哦。也许你会认为我瞎说,那么就来看一下两者Transaction Scope Option上的对比吧。
         首先,Transaction Scope主要是解决在方法调用过程中Transaction嵌套的问题。ADO.net 2.0在Transaction Scope上提供的
Option有三个:RequireRequires NewSuppress。在idior兄的Post里面,还有一张表和一个示意图,你是否都看懂了呢?表中列出的六种情况,你又是否了然于胸了呢?以下图表引用于idior兄的Post

TranactionList.Jpeg

TransactionInADO.Jpeg

        1. 表中的第一行对应着图中Code block with no ambient Transaction对Scope1的调用。对照表中的第三列:New

Transaction。我们可以得出,当一个与Transaction无关的MethodA调用了Transaction Scope为Required的MethodB,Transaction Manager将会为MethodB创建一个新的Transaction,这个新的Transaction就对应着图中Transaction A。
        2. 表中的第二行在图中没有画出来,可类比第五行。
        3. 表中的第三行在图中没有画出来,可类比第六行。
        4. 表中的第四行在图中对应着Scope1对Scope2的调用。对照表中的第三列:Ambient Transaction。 我们可以得出, 当一个与
Transaction有关的MethodA调用了Transaction Scope为Required的MethodB, Transaction Manager并不会创建新的Transaction,而是让MethodB与MethodA所在的Tranaction关联起来。
        5. 表中的第五行在图中对应着Scope1对Scope3的调用。对照表中的第三列:New Transaction。我们可以得出,当一个与
Transaction有关的MethodA调用了Transaction Scope为Requires New的MethodB, Transaction Manager会为MethodB创建一个新的Transaction,这个新的Transaction就对应着图中的TransactionB了。
        6. 表中的第六行在图中对应着Scope1对Scope4的调用。对照表中的第三列:No Transaction。我们可以得出,当一个与
Transaction有关的MethodA调用了Transaction Scope为Suppress的MethodB, Transaction Manager既不会为MethodB创建新的Transaction,也不会将MethodB与MethodA所在的Transaction关联起来。
        总之,Required会视调用者的情况决定是否创建新的Transaction,而另外两个Option则不管调用者的情况如何,都会有一致的结果。打个比方吧,Required意味着精打细算,原来存在Transaction就拿来用,没有才会创建一个新的;Requires New就意味着要求纯粹了,不管你原来有没有Transaction,到了偶的地盘都得有Transaction;Suppress就是不理不睬了,管你原来有没有Transaction,反正俺这里不要。
  
        说完了ADO.net的情况,就让我们来看看J2EE下面的Transaction Scope Option吧。在J2EE的文档中,会有一个特别的名词
Transaction Attribute与ADO.net的Transaction Scope Option想对应。 Transaction Attribute有六个可选值:Required,Requires New,Mandatory,Not Supported,Supports和Never。为了不再重复上面繁琐的陈述,还是用下面的图表来说明这几种Attribute的含义吧:

Transaction.gif

        

Scope1.gif

 Figure1.  Invoker with no client transaction
        

Scope2.gif

Figure2.  Invoker with client transaction

       从以上的图表,你可以发现两者的Required和Requires New是对应的,而Not Supported则对应于ADO.net中的Suppress。而Mandatory,Supports和Never则是J2EE下特有的。正是因为增加了这三个Attributes,所覆盖的可能性范围就增大了许多,处理Transaction Scope的问题也相应变得更加灵活,更能满足复杂业务逻辑的需要了。

原文地址:https://www.cnblogs.com/zhouyunbaosujina/p/3385629.html