在Entity framework中使用事務

來源:互聯網
上載者:User

標籤:name   官方   art   手動   .exe   不能被繼承   操作   .net   需要   

預設情況下,當EF調用SaveChanges()時,會把產生的所有SQL命令“包”到一個“事務(transaction)”中,只要有一個資料更新操作失敗,整個事務將復原。
在多數情況下,如果你總在資料更新作業碼中使用一個而不是多個DbContext對象,並且只是在最後調用一次SaveChanges(),那麼EF的預設交易處理機制己經夠用了,無需做額外的事情。
然而,如果出現以下的情形,你就必須顯式地處理事務了。


第一種情況:你需要分階段地儲存資料,因而需要多次調用SaveChanges()或者執行修改資料庫的SQL命令。


請看以下範例程式碼:

using (var context = new MyDbContext()){    try     {        Person3 p = context.People3.First();        p.Name ="newName" + (new Random().Next(1, 100));        context.SaveChanges();        context.Database.ExecuteSqlCommand("update Person3 setDescription={0} where Person3Id={1}",                            "DescriptionModified at " + DateTime.Now.ToShortTimeString(),                            p.Person3Id);        p.age *= 2;        context.SaveChanges();    }    catch (Exception e)    {        Console.WriteLine(e.Message);    }}

上述代碼中,調用兩次SaveChanges(),還有一次執行Update命令。
如果在最後一次SaveChanges()中出現異常,雖然最後一次沒成功,但你會發現前兩次資料己經儲存!這就帶來了資料不一致的問題。
對於這種情境,你需要顯式地編寫事務代碼了(註:以下代碼適用於EF6):

using (var context = new MyDbContext()) {    using (var transaction =context.Database.BeginTransaction())    {        try        {              ……               context.SaveChanges();               context.Database.ExecuteSqlCommand("……);               ……               context.SaveChanges();              transaction.Commit();          }        catch (Exception e)        {               Console.WriteLine(e.Message);               transaction.Rollback();        }    }}

特別要注意一定要調用commit(),我測試發現,只要不Commit,即使沒有異常發生,事務仍將復原,資料庫中的資料不會更新。

 

 

第二種情況,你需要使用多個DbContext儲存資料,這種情況使用TransactionScope來提交事務

 

TransactionScope位於using System.Transactions;命名空間下,需要在引用中手動加入。該類不能被繼承。

    //    // 摘要:    //     使代碼塊成為事務性代碼。此類不能被繼承。    public sealed class TransactionScope : IDisposable

 

常用參數

  1. TransactionScopeOption
    //// 摘要://     該範圍需要一個事務。如果已經存在環境事務,則使用該環境事務。否則,在進入範圍之前建立新的事務。這是預設值。Required = 0,//// 摘要://     總是為該範圍建立新事務。RequiresNew = 1,//// 摘要://     環境事務上下文在建立範圍時被取消。範圍中的所有操作都在無環境事務內容相關的情況下完成。Suppress = 2

     

  2. TimeSpan設定逾時時間
            //        // 摘要:        //     以指定的逾時時間值和要求初始化 System.Transactions.TransactionScope 類的新執行個體。        //        // 參數:        //   scopeOption:        //     System.Transactions.TransactionScopeOption 枚舉的一個執行個體,描述與此事務範圍關聯的事務要求。        //        //   scopeTimeout:        //     在 System.TimeSpan 之後,事務範圍將逾時並中止此事務。        public TransactionScope(TransactionScopeOption scopeOption, TimeSpan scopeTimeout);

     

優點:

  1. 使用起來比較方便.TransactionScope可以實現隱式的事務,使你可以在寫資料訪問層代碼的時候不用考慮到事務,而在業務層的控制事務.
  2. 可以實現分散式交易,比如跨庫或MSMQ.
  3. 在EntityFramework中可以解決DbContextTransaction的多個上下文出現死結問題。也就是說在EF中使用TransactionScope事務時,不用考慮資料庫操作的多上下文問題。

缺點:

  1. 此種方式對於資料庫鎖定表,會影響其他進程的查詢,也就是對於鎖定的表,查詢也鎖定,不允許出現髒讀,其他的查詢需要掛起等待。重點是不能進行配置修改。
  2. 此種方式對於同一個範圍/同一個邏輯操作,需要進行多線程的鎖定處理,不然多個線程開啟同一個事務會拋出異常。
  3. 多個事務操作中,存在鎖定同一個表的時候也會出現死結現象

使用執行個體如下:

Test1 _context = new Test1();Test1 _context2 = new Test1();using (TransactionScope tran = new TransactionScope()){    try    {        //1.修改省        Area province = _context.Areas.FirstOrDefault(q => q.AreaLevel == 1);        province.AreaName = province.AreaName + "1";        _context.SaveChanges();        Console.WriteLine(_context2.Areas.FirstOrDefault(q => q.AreaLevel == 1).AreaName);        //2.修改市        Area city = _context2.Areas.FirstOrDefault(q => q.AreaLevel == 2);        city.AreaName = city.AreaName + "1";        _context2.SaveChanges();        //拋出異常        throw new Exception("測試事務異常");        tran.Complete();    }    catch (Exception ex)    {        Console.WriteLine("執行出錯:" + ex.Message);    }}

特別說明:
如果你的上下文(DbContext)在程式中只有一個,那麼如果執行事務期間出現異常造成交易回復,會出現資料模型和資料庫中資料不對應情況,也就是說資料庫的操作雖然被復原了,但是EF中每個資料模型的狀態卻變成了事務提交後的了,但是實際上事務被復原了。針對這個問題目前官方給的建議是,EF中如果交易回復,就拋棄老的上下文(DbContext),使用一個新的上下文(DbContext)。

 

 

參考文獻:

EntiryFramework中事務操作(二)TransactionScope

EntityFramework 交易處理

 

在Entity framework中使用事務

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.