1. 程式人生 > >EF6學習筆記二十五:分布式事務

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

db2 分享 rect dtc 發現 fck row ffd 類型

要專業系統地學習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不可用的問題。行吧,就到這裏。

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