zoukankan      html  css  js  c++  java
  • 使用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的问题也相应变得更加灵活,更能满足复杂业务逻辑的需要了。

  • 相关阅读:
    什么是32位汇编的flat平坦内存模式
    oracle随机操作
    网线8根排列顺序
    vb创建NT服务
    函数声明后面加个stdcall是什么意思
    一些基础问题。
    ArcGIS Server中地图打印的实现
    添加BaseCommand 和Base Tool 的注意事项
    获取字符串中的某个子字符串
    AE, C#,按纸张打印地图
  • 原文地址:https://www.cnblogs.com/zhouyunbaosujina/p/3385629.html
Copyright © 2011-2022 走看看