zoukankan      html  css  js  c++  java
  • TransactionScope

    本文来自:http://www.cnblogs.com/huangyangblogs/p/3305602.html

    最近发现微软自带的TransactionScope(.Net Framework 2之后)是个好东东,提供的功能也很强大。

      首先说说TransactionScope是什么,并能为我们做什么事情。其实看Transaction(事务)这个单词,我想大家已经能猜到个大概。不同于SqlTransaction的事务,因为现在做的项目都有不同的分层架构,如果不在数据库操作层里面做的话,那么使用TransactionScope是一种理想的方式,它是一个轻量级的事务类。所谓事务,就好比两个串联的开关,控制着一个灯泡,这两个开关可以理解为一个独立的单位,要么都开,否则灯泡就亮不起来。在程序里面就是要么都正常执行,如果中间有异常,事务就会出现回滚操作。回滚操作相当于回到操作之前的状态,可以理解为没有操作。这里面,事务是针对数据库的一种行为。

      要想使用TransactionScope,很方便,只需要在项目中添加System.Transactions.dll引用,然后添加命名空间(using System.Transactions;)即可。

      我们来看看微软的TransactionScope类:

        public sealed class TransactionScope : IDisposable
        {
            public TransactionScope();
            public TransactionScope(Transaction transactionToUse);
            public TransactionScope(TransactionScopeOption scopeOption);
            public TransactionScope(Transaction transactionToUse, TimeSpan scopeTimeout);
            public TransactionScope(TransactionScopeOption scopeOption, TimeSpan scopeTimeout);
            public TransactionScope(TransactionScopeOption scopeOption, TransactionOptions transactionOptions);
            public TransactionScope(Transaction transactionToUse, TimeSpan scopeTimeout, EnterpriseServicesInteropOption interopOption);
            public TransactionScope(TransactionScopeOption scopeOption, TransactionOptions transactionOptions, EnterpriseServicesInteropOption interopOption);

            public void Complete();
            public void Dispose();
        }

      sealed关键字修饰类,说明该类不能被继承。该类提供多种构造函数及Complete()和Dispose()方法.

      =》Complete()即为提交事件的方法

      =》Dispose()即释放事务对象的方法

      (1)TransactionScopeOption参数,该参数是一个枚举类型:

        public enum TransactionScopeOption
        {

       Required = 0,
       RequiresNew = 1,
       Suppress = 2
        }

      Required=》该范围需要一个事务。 如果已经存在事务,则使用该事务。

            否则,在进入范围之前创建新的事务。 这是默认值。

      RequiresNew=》总是为该范围创建新事务

      Suppress=》事务上下文在创建范围时被取消。 范围中的所有操作都在无事务上下文的情况下完成。

      通过查看 System.Transactions.Transaction.Current 属性。如果这个属性为“null”,说明不存在当前事务。

      (2)TransactionOptions参数,包含指定事务行为的附加信息。

     public struct TransactionOptions
        {

        。。。。。。

            public IsolationLevel IsolationLevel { get; set; }
            public TimeSpan Timeout { get; set; }
        }

      如果要修改 TransactionScope 的默认设置,可以实例化TransactionOptions对象,并对该对象传递需要的参数。可以通过它在 TransactionScope 对象上设置隔离级别和事务的超时时间。

      IsolationLevel=》设置隔离级别

     Serializable           可以在事务期间读取可变数据,但是不可以修改,也不可以添加任何新数据。 
     RepeatableRead    可以在事务期间读取可变数据,但是不可以修改。 可以在事务期间添加新数据。  
     ReadCommitted    不可以在事务期间读取可变数据,但是可以修改它。 
     ReadUncommitted 可以在事务期间读取和修改可变数据。 
     Snapshot             可以读取可变数据。在事务修改数据之前,它验证在它最初读取数据之后另一个事务是否更改过这些数据。如果数据已被更新,则会引发错误。这样使事务可获取先前提交的数据值。在尝试提升以此隔离级别创建的事务时,将引发一个InvalidOperationException,并产生错误信息“Transactions with IsolationLevel Snapshot cannot be promoted”(无法提升具有 IsolationLevel 快照的事务)。
     Chaos 无法覆盖隔离级别更高的事务中的挂起的更改。 
     Unspecified 正在使用与指定隔离级别不同的隔离级别,但是无法确定该级别。如果设置了此值,则会引发异常。   

      Timeout=》设置事务的超时时间(默认设置为 1 分钟)

     TimeSpan(Int64)                                        将新的 TimeSpan 初始化为指定的刻度数。 
     TimeSpan(Int32, Int32, Int32)                     将新的 TimeSpan 初始化为指定的小时数、分钟数和秒数。 
     TimeSpan(Int32, Int32, Int32, Int32)            将新的 TimeSpan 初始化为指定的天数、小时数、分钟数和秒数。 
     TimeSpan(Int32, Int32, Int32, Int32, Int32)   将新的 TimeSpan 初始化为指定的天数、小时数、分钟数、秒数和毫秒数。

      (3)下面举一个例子说明怎么使用,主要看红色部分的代码,红色部分代码即为使用TransactionScope的例子。用很少的几行代码就可以实现轻量级TransactionScope事务。


            public void FixProjectSorceInsert()
            {
                TransactionOptions transactionOption = new TransactionOptions();
                //设置事务隔离级别
                transactionOption.IsolationLevel = System.Transactions.IsolationLevel.ReadCommitted;
                // 设置事务超时时间为120秒
                transactionOption.Timeout = new TimeSpan(0, 0, 120);

                using (TransactionScope scope = new TransactionScope(TransactionScopeOption.Required, transactionOption))
                {
                    try
                    {
                        Insert();

                        Update();

                        Delete();

                        // 没有错误,提交事务
                        scope.Complete();
                    }
                    catch (Exception ex)
                    {
                        throw new Exception("发送信息异常,原因:" + ex.Message);
                    }
                    finally
                    {
                        //释放资源
                        scope.Dispose();
                    }

                }
            }

      (4)小结:使用事务,就像使用一把锁,会锁定资源。资源总是有限,所以进入和退出事务都要控制在较短的时间。在需要使用事务前创建它,在需要执行时打开连接,并尽快完成释放事务。而且在事务执行中,尽可能避免执行不必要或与数据库操作无关的代码,因为这能够防止资源被过度锁定。

  • 相关阅读:
    scikit-learn
    caffe
    大型云原生项目在数字化企业落地过程解密
    「澳洋主数据项目」主数据促企业变革
    Docker镜像仓库清理的探索之路
    用友云开发者中心助你上云系列之在线调试
    如何精简企业主数据“裹脚布”
    企业推动移动化战略中为什么需要Moli?
    欧派家居牵手用友云平台 打造标准化数据资产管理平台
    用友云开发者中心,你应该知道的那些事
  • 原文地址:https://www.cnblogs.com/zhouyunbaosujina/p/3730859.html
Copyright © 2011-2022 走看看