C# TransactionScope 事務類


微軟自帶的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 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)小結:使用事務,就像使用一把鎖,會鎖定資源。資源總是有限,所以進入和退出事務都要控制在較短的時間。在需要使用事務前創建它,在需要執行時打開連接,並盡快完成釋放事務。而且在事務執行中,盡可能避免執行不必要或與數據庫操作無關的代碼,因為這能夠防止資源被過度鎖定。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM