C# TransactionScope 事務類

微軟自帶的TransactionScope(.Net Framework 2以後)是個好東東,提供的功能也很強大。數據庫

  首先說說TransactionScope是什麼,並能爲咱們作什麼事情。其實看Transaction(事務)這個單詞,我想你們已經能猜到個大概。不一樣於SqlTransaction的事務,由於如今作的項目都有不一樣的分層架構,若是不在數據庫操做層裏面作的話,那麼使用TransactionScope是一種理想的方式,它是一個輕量級的事務類。所謂事務,就比如兩個串聯的開關,控制着一個燈泡,這兩個開關能夠理解爲一個獨立的單位,要麼都開,不然燈泡就亮不起來。在程序裏面就是要麼都正常執行,若是中間有異常,事務就會出現回滾操做。回滾操做至關於回到操做以前的狀態,能夠理解爲沒有操做。這裏面,事務是針對數據庫的一種行爲。架構

  要想使用TransactionScope,很方便,只須要在項目中添加System.Transactions.dll引用,而後添加命名空間(using System.Transactions;)便可。函數

  咱們來看看微軟的TransactionScope類:ui

    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);spa

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

  sealed關鍵字修飾類,說明該類不能被繼承。該類提供多種構造函數及Complete()和Dispose()方法.繼承

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

  =》Dispose()即釋放事務對象的方法事務

  (1)TransactionScopeOption參數,該參數是一個枚舉類型:ci

    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 bool FixProjectSorceInsert()
        {
            bool result = true;
            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);
                    result = false;
                }
                finally
                {
                    //釋放資源
                    scope.Dispose();
                }

            }
            return result;
        }

  (4)小結:使用事務,就像使用一把鎖,會鎖定資源。資源老是有限,因此進入和退出事務都要控制在較短的時間。在須要使用事務前建立它,在須要執行時打開鏈接,並儘快完成釋放事務。並且在事務執行中,儘量避免執行沒必要要或與數據庫操做無關的代碼,由於這可以防止資源被過分鎖定。

相關文章
相關標籤/搜索