如今假設有兩個表如圖:數據庫
表TA 表TB ide
現有數據: spa
如今的需求是:每往TA中插入一條數據,就更新TB的第一行,值爲表TA的全部行的Age的平均值3d
能夠看到表TB的Remark長度僅僅爲2,待會利用這個製造錯誤code
using (EFTestEntities db = new EFTestEntities()) { //數據庫TA原有2行,此時添加第3行 var aEntity = new TA { Name = "a", Age = 20 }; db.TA.Add(aEntity); var listTA = db.TA.ToList();//此時list只有2行,新添加的沒有讀取到 int totalAge = 0; listTA.ForEach(p => totalAge += p.Age); //獲取表TB的第一行,並修改AvgAge值 var bEntity = db.TB.First(); bEntity.AvgAge = totalAge / listTA.Count; bEntity.Remark = "bb"; db.SaveChanges(); //結果是Tb的值沒有變化 }
你認爲是添加TA後沒有db.SaveChanges();? 的確,添加這個以後,能夠讀取到新添加的值了,可是沒有事務了,如:blog
using (EFTestEntities db = new EFTestEntities()) { //數據庫TA原有2行,此時添加第3行 var aEntity = new TA { Name = "a", Age = 20 }; db.TA.Add(aEntity); db.SaveChanges(); var listTA = db.TA.ToList();//此時list有3行了,新添加的能夠被讀取到 int totalAge = 0; listTA.ForEach(p => totalAge += p.Age); //獲取表TB的第一行,並修改AvgAge值 var bEntity = db.TB.First(); bEntity.AvgAge = totalAge / listTA.Count; bEntity.Remark = "bbc";//故意超出長度,製造錯誤 db.SaveChanges(); //結果是TA添加了新行,可是TB修改時出錯致使修改失敗。形成了數據不一致 }
結果是TA添加了新行,可是TB由於remark超出長度致使致使修改失敗,此時TB的數據是錯的。事務
怎樣能夠避免這個問題?答案就是用事務。rem
using (EFTestEntities db = new EFTestEntities()) { using (TransactionScope ts = new TransactionScope()) { //數據庫TA原有2行,此時添加第3行 var aEntity = new TA { Name = "a", Age = 20 }; db.TA.Add(aEntity); db.SaveChanges();//重點,必需要db.SaveChanges(),而後下面才能獲取到新添加的行 var listTA = db.TA.ToList();//此時list有3行了,新添加的能夠被讀取到 int totalAge = 0; listTA.ForEach(p => totalAge += p.Age); //獲取表TB的第一行,並修改AvgAge值 var bEntity = db.TB.First(); bEntity.AvgAge = totalAge / listTA.Count; bEntity.Remark = "bbc";//故意超出長度,製造錯誤 db.SaveChanges(); //執行到此處程序報錯 ts.Complete();//事務提交未執行 //結果是自動回滾,至關於這次沒有對數據庫作任何操做。保持了數據一致性 } }
下面給出正確的示例,實現以上需求:it
using (EFTestEntities db = new EFTestEntities()) { using (TransactionScope ts = new TransactionScope()) { //數據庫TA原有2行,此時添加第3行 var aEntity = new TA { Name = "a", Age = 20 }; db.TA.Add(aEntity); db.SaveChanges();//重點,必需要db.SaveChanges(),而後下面才能獲取到新添加的行 var listTA = db.TA.ToList();//此時list有3行了,新添加的能夠被讀取到 int totalAge = 0; listTA.ForEach(p => totalAge += p.Age); //獲取表TB的第一行,並修改AvgAge值 var bEntity = db.TB.First(); bEntity.AvgAge = totalAge / listTA.Count; bEntity.Remark = "bb";//數據符合規範 db.SaveChanges(); //保存 ts.Complete();//提交事務 //結果是執行成功,TA多一條數據,同時TB的值也變了 } }
一切都nice了!io