中文字幕精品亚洲无线码二区,国产黄a三级三级三级看三级,亚洲七七久久桃花影院,丰满少妇被猛烈进入,国产小视频在线观看网站

DotNetCore跨平臺~EFCore廢棄(qi)了TransactionScope取而代之(zhi)的Context.Database.BeginTransaction

回到目錄

TransactionScope是.net平臺基于的(de)分(fen)布式(shi)事(shi)務(wu)(wu)組件,它默(mo)認為(wei)本地事(shi)務(wu)(wu),同時(shi)當系(xi)統有需要時(shi)可以自(zi)動提升為(wei)分(fen)布式(shi)事(shi)務(wu)(wu),而(er)對系(xi)統的(de)前提是要開啟MSDTC服(fu)務(wu)(wu),必要時(shi)需要在(zai)數(shu)據(ju)庫服(fu)務(wu)(wu)器與應(ying)用服(fu)務(wu)(wu)器之(zhi)間添(tian)加hosts的(de)映射,這些在(zai)之(zhi)前已經寫過很(hen)多文章了(le),在(zai)這里不再說了(le)。

之(zhi)前對TransactionScope的一些理(li)解和總結

第二十六回   將不確定變為確定~transactionscope何時提升為分布式事務?

第二十七回   將不確定變為確定~transactionscope何時提升為分布式事務~續

第二十八回   將不確定變為確定~transactionscope何時提升為分布式事務~再續(避免引起不必要的MSDTC)

第三十七回   將不確定變為確定~transactionscope何時提升為分布式事務~SQL2005與SQL2008不同

第三十八回   將不確定變為確定~transactionscope何時提升為分布式事務?(sql2005數據庫解決提升到MSDTC的辦法)

在efcore平臺(tai)時,你(ni)使用TransactionScope將會(hui)出(chu)現異常,微軟會(hui)提示你(ni)去查(cha)看相關資(zi)(zi)料,這回資(zi)(zi)料挺(ting)準(zhun)!//docs.microsoft.com/en-us/ef/core/saving/transactions

本文(wen)章主要(yao)說了幾(ji)點內容

  1. 默認的事務-savechanges依舊是一個事務
  2. 單個上下文實現事務
  3. 不同上下文之間實現事務

一 savechanges依(yi)舊是(shi)一個(ge)事務

和之前(qian)的ef一樣,在進行saveChanges()操作(zuo)(zuo)時,本身(shen)就(jiu)是一個事務(wu)塊,而大(da)叔倉儲習慣把每個操作(zuo)(zuo)curd都有自(zi)己(ji)的saveChanges里,而把數據(ju)(ju)上下文的savechanges對外隱藏,所以如(ru)果你(ni)要對兩個倉儲進行insert操作(zuo)(zuo)時,你(ni)需要添加一個外層的事務(wu)來保(bao)證數據(ju)(ju)一致(zhi)性,這時微軟給出了解(jie)決方(fang)案。

二 單個上下文實現事(shi)務

對于一個數據上下文來說,如果你是多個savechanges,那么可以使用context.Database.BeginTransaction()來實現事務。

  using (var context = new BloggingContext())
        {
            using (var transaction = context.Database.BeginTransaction())
            {
                try
                {
                    context.Blogs.Add(new Blog { Url = "//blogs.msdn.com/dotnet" });
                    context.SaveChanges();

                    context.Blogs.Add(new Blog { Url = "//blogs.msdn.com/visualstudio" });
                    context.SaveChanges();

                    var blogs = context.Blogs
                        .OrderBy(b => b.Url)
                        .ToList();

                    // Commit transaction if all commands succeed, transaction will auto-rollback
                    // when disposed if either commands fails
                    transaction.Commit();
                }
                catch (Exception)
                {
                    // TODO: Handle failure
                }
            }
        }

三 不(bu)同(tong)上下(xia)文之(zhi)間實現事務

對于前面的(de)(de)(de)TransactionScope來(lai)說(shuo),如果(guo)是不同(tong)的(de)(de)(de)數(shu)據上下文來(lai)說(shuo),我們(men)是無法實現(xian)事務操作的(de)(de)(de),有些同(tong)學可以(yi)能說(shuo)它應(ying)該被(bei)提升為分布(bu)式的(de)(de)(de),但對于EF來(lai)說(shuo),它是不同(tong)實現(xian)的(de)(de)(de),但進行(xing)efcore時代(dai)之(zhi)后,這個問題得到(dao)了解決!

Cross-context transaction (relational databases only)

You can also share a transaction across multiple context instances. This functionality is only available when 
using a relational database provider because it requires the use of DbTransaction and DbConnection,
which are specific to relational databases.

上面說明,可以實現一個跨數據上下文的事務,只關系型數據庫支持!這個功能大叔認為非常必要,但看(kan)它下面給出的(de)實例是針對(dui)一個數據上下文(wen)的(de),并不多個上下文(wen)的(de)交

叉事務,即并不是兩(liang)個數據(ju)庫(ku)之間的事務

       using (var context1 = new BloggingContext(options))
        {
            using (var transaction = context1.Database.BeginTransaction())
            {
                try
                {
                    context1.Blogs.Add(new Blog { Url = "//blogs.msdn.com/dotnet" });
                    context1.SaveChanges();

                    using (var context2 = new BloggingContext(options))
                    {
                        context2.Database.UseTransaction(transaction.GetDbTransaction());

                        var blogs = context2.Blogs
                            .OrderBy(b => b.Url)
                            .ToList();
                    }

                    // Commit transaction if all commands succeed, transaction will auto-rollback
                    // when disposed if either commands fails
                    transaction.Commit();
                }
                catch (Exception)
                {
                    // TODO: Handle failure
                }
            }
        }

而如果(guo)真正使用多(duo)個上下文(wen)進行(xing)事(shi)務的(de)話(hua),同樣會出現問題:

           var options = new DbContextOptionsBuilder<DemoContext>()
                          .UseMySql("Server=localhost;DataBase=test2;UID=root;Password=root;charset=utf8;port=3306;SslMode=None")
                          .Options;
            using (var context = new DemoContext(options))
            {
                using (var transaction = context.Database.BeginTransaction())
                {
                    var user = new UserInfo
                    {
                        AddTime = DateTime.Now,
                        Email = "test@sina.com",
                        UserName = "test"
                    };
                    context.UserInfo.Add(user);
                    context.SaveChanges();
                    using (var context2 = new TaxContext())
                    {
                        context2.Database.UseTransaction(transaction.GetDbTransaction());
                        context2.UserInfo.Add(new UserInfo { AddTime = DateTime.Now, Email = "tax_test", UserName = "tax" });
                        context2.SaveChanges();
                    }
                    transaction.Commit();
                }
            }

出現下面(mian)異常(chang):告訴你,你的(de)數(shu)據庫(ku)連接不是當前的(de)連接

System.InvalidOperationException:“The specified transaction is not associated with the current connection.
Only transactions associated with the current connection may be used.”

不知(zhi)道什么時候EF可以解(jie)決多數(shu)據庫事(shi)務(wu)的問(wen)題,當前(qian)你(ni)可以使用(yong)最終一(yi)致性的分布(bu)式事(shi)務(wu)來做(zuo)這事(shi),不過(guo)我們還是一(yi)起期待中微軟為我們提出更簡單的解(jie)決方(fang)案,一(yi)個事(shi)務(wu)

是(shi)(shi)否(fou)為(wei)分布式的,應該看數據庫所在服(fu)務器是(shi)(shi)否(fou)相同,而不是(shi)(shi)數據庫連接串(chuan)是(shi)(shi)否(fou)一致!

感謝微軟這么(me)完整的解釋(shi)!

 回到目錄

posted @ 2017-10-13 10:40  張占嶺  閱讀(5060)  評論(1)    收藏  舉報