EF中關於TransactionScope的使用

前提條件

 

TransactionScope類須要引用System.Transactions;

 

 

數據庫環境及需求

如今假設有兩個表如圖:數據庫

                                      

 

 

           表TA                                                                                  表TB ide

 

 

現有數據:                                            spa

 

 

 

 

 

 如今的需求是:每往TA中插入一條數據,就更新TB的第一行,值爲表TA的全部行的Age的平均值3d

 能夠看到表TB的Remark長度僅僅爲2,待會利用這個製造錯誤code

 

 

 

當不使用TransactionScope時:

 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的值沒有變化
            }  
View Code

 

你認爲是添加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修改時出錯致使修改失敗。形成了數據不一致
            }  
View Code

 

結果是TA添加了新行,可是TB由於remark超出長度致使致使修改失敗,此時TB的數據是錯的。事務

 

怎樣能夠避免這個問題?答案就是用事務。rem

 

使用TransactionScope:

 

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();//事務提交未執行
                    //結果是自動回滾,至關於這次沒有對數據庫作任何操做。保持了數據一致性
                }
            }
View Code

 

 下面給出正確的示例,實現以上需求: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的值也變了
                }
            }
View Code

 

 

一切都nice了!io

相關文章
相關標籤/搜索