EF6學習筆記二十五:分布式事務


要專業系統地學習EF推薦《你必須掌握的Entity Framework 6.x與Core 2.0》。這本書作者(汪鵬,Jeffcky)的博客:https://www.cnblogs.com/CreateMyself/

現在來到分布式事務。在弄這個之前我對分布式一點經驗也沒有。簡單來說一下分布式,就是你有多個數據庫。

不過我碰到的“MSDTC不可用”的問題實在是無法解決。所以只能是記錄一下我遇到的問題,和一些過程。

上次我們知道平時一般的操作,都是會默認被事務包裹,當我們調用一次SaveChanges方法就會開啟一個事務。

然后了解到EF中提供的BeginTransaction()和UseTransaction()兩個方法。

BeginTransaction()能夠讓我們像ADO中使用事務的那種方式使用。而且調用多個savechanges方式只會開啟一個事務,但是必須要調用一次SaveChanges才能成功操作數據。

UseTransaction方法允許上下文加入已經運行的事務中,它可以接受一個事務對象。

那么如果我們的數據存在多個數據庫中呢?就有了分布式的考慮。怎么做呢?

你可能想到可以通過嵌套上下文,使用UseTransaction來接受另一個上下文的事務。但是不可以。因為UseTransaction接受的事務對象不是EF中定義的事務,而是System.Data.Common.DbTransaction類型的,也就是ADO中的事務類型

那么我們ado和EF混着用?這個應該是可以的,但是我沒有去試。

那么現在就直接來說一個很重要的類:TransactionScop

可以看到這種方式正是我們想要的,DB1_Context 和 DB4_Context 分別對應兩個數據庫,一個本地,還有一個是我遠程服務器上的數據庫。 通過TransactionScop就可以實現分布式事務。

using (var scope = new TransactionScope(TransactionScopeOption.RequiresNew))
{
    var db1_ctx = new DB1_Context();
    var db4_ctx = new DB4_Context();
    try
    {
        db1_ctx.Students.Add(new Student { Name = "小懵", Score = 11 });
        db1_ctx.SaveChanges();

        db4_ctx.Books.Add(new Book { Name="西游記",PageSize=670});
        db4_ctx.SaveChanges();
        scope.Complete();
    }
    catch (Exception e)
    {
        throw e;
    }
    finally
    {
        db1_ctx.Dispose();
        db4_ctx.Dispose();
    }
}
View Code

看一下我項目的文件結構

這里我要記錄一下使用程序包管理控制台做數據遷移,將不同的上下文分別創建不同的文件夾

比如我為DB1_Context上下文開啟遷移

enable-migrations -ContextTypeName:_20190131.DbContexts.DB1_Context -MigrationsDirectory:Migrations\DB1

ContextTypeName就是上下文的類型名稱,MigrationsDirectory就是你將要創建的文件夾

如果說你記不住命令,可以寫了“-”后按Tab鍵就會出現提示。如果說沒有提示,那么就是你前面的語句寫錯了。命令不同區分大小寫,但是你自己提供的值還是要區分的,畢竟DBContext和dbcontext在VS中還是兩個不同的兩個類

命令后面的冒號可寫可不寫,比如:ContextTypeName:DBcontext  或者 ContextTypeName DBcontext  我還是覺得寫上問號好一點,可讀性高。

那么添加遷移文件

add-migration -ConfigurationTypeName:_20190131.Migrations.DB1.Configuration -Name:db1001

更新到數據庫

update-database -ConfigurationTypeName:_20190131.Migrations.DB1.Configuration -verbose

現在來記錄一下我碰到的問題,我也不知道會這么麻煩,對我來說不過是多了一個數據庫而已。

首先我通過EF在MSSQL上的一個實例創建了兩個數據庫DB1和DB2,於是我執行上面的代碼,發現報錯了,他說MSDTC不可用。

那么MSDTC是什么?協調跨多個數據庫、消息隊列、文件系統等資源管理器的事務。如果停止此服務,這些事務將會失敗。如果禁用此服務,顯式依賴此服務的其他服務將無法啟動。

 

反正涉及到分布式就需要配置MSDC,網上有很多圖文並茂的配置,但都是一樣的。難道都不一樣么?難道怎么配置都行么?呵呵

最終我沒有解決這個問題。

然后我想到是不是因為兩個數據庫都是在本地,都是在同一個實例中造成的。於是我今天又在我的服務器上安裝了一個MSSQL2017,費了

老半天勁終於我本地數據庫能夠連接遠程服務器的數據庫實例了。

但是還是出席那MSDTC不可用的問題。行吧,就到這里。 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM