2016-05-08 106 views
0

當在上下文中調用SaveChanges()時,所有插入/刪除/更新操作都將在單個事務中執行。也可以爲事務使用DbContextTransaction。我試圖用這兩種方法來模擬死鎖。當我使用DbContextTransaction時,立即得到死鎖異常,但即使在一小時後,SaveChanges()本身也不會引發任何死鎖異常。難道我做錯了什麼?實體框架事務和死鎖

這是DbContextTransaction的代碼。我嘗試更新第一行,然後更新主線程中的第二行。我還開始另一項任務,嘗試先更新第二行,然後再更新第一行。

 while (true) 
     { 
      using (var context = new SchoolDBEntities()) 
      { 
       using (System.Data.Entity.DbContextTransaction dbTran = context.Database.BeginTransaction()) 
       { 
        Random r = new Random(); 
        int r1 = r.Next(); 
        int r2 = r.Next(); 

        Student std1 = context.Students.First(); 
        std1.StudentName = "test"+r1; 
        context.SaveChanges(); 

        Student std2 = context.Students.Find(2); 
        std2.StudentName = "test"+r2; 
        context.SaveChanges(); 

        dbTran.Commit(); 

       } 

      } 
     } 

但是,當我只嘗試的SaveChanges它()它不會產生死鎖:

 while (true) 
     { 
      using (var context = new SchoolDBEntities()) 
      { 
       try 
       { 
        Random r = new Random(); 
        int r1 = r.Next(); 
        int r2 = r.Next(); 

        Student std1 = context.Students.First(); 
        std1.StudentName = "test" + r1; 
        Student std2 = context.Students.Find(2); 
        std2.StudentName = "test" + r2; 

        context.SaveChanges(); 
       } 
      } 
     } 

我使用SQL事件探查器跟蹤交易。我甚至爲第二種方法添加了更多更新,只是爲了讓事務的持續時間等於DbContextTransaction案例,認爲這可能是原因,但仍然沒有運氣!當我查看跟蹤時,我發現屬於特定事務的更新僅在上次事務提交後纔會啓動。可能是什麼原因?

回答

0

經過進一步調查,我發現無上下文對上下文做出的更改順序,SaveChanges()方法始終將更新查詢發送到SQL Server的順序基於表的主鍵。換句話說,即使我嘗試通過首先更改第2行然後第1行來顛倒更新請求的順序,SaveChanges()首先執行第1行然後第2行的更新查詢。這就是爲什麼我沒有得到通過使用SaveChanges()方法來死鎖。它不會顛倒查詢的順序。