首先使用EF 5代碼和.NET 4.5的MVC項目。在單個事務中包裝成員資格提供程序和dbcontext
我正在尋找一種方法來在單個事務上包裝dbContext和SimpleMembershipProvider。我試圖使用TransactionScope,但由於成員資格提供者將打開另一個連接,我得到一個異常(服務器'servername'上的MSDTC不可用)。
所以我雖然可以使用ObjectContext.Connection.BeginTransaction代替。 成員資格提供者不會成爲交易的一部分,但想法是讓它在某個地方,如果它失敗,交易將不會被提交。
Book bk1 = default(Book);
Book bk2 = default(Book);
object obc = (IObjectContextAdapter)dbContext;
obc.ObjectContext.Connection.Open();
using (tx == obc.ObjectContext.Connection.BeginTransaction) {
bk1 = new Book {
Name = "Book 1 Name",
Location = "USA"
};
dbContext.Books.Add(bk1);
dbContext.SaveChanges();
bk2 = new Book {
Name = "Book 2 Name. Book one Id is: " + bk1.Id,
Location = "USA"
};
dbContext.Books.Add(bk2);
dbContext.SaveChanges();
// this is not part of the transaction,
// however if it trhows an exception the transaction is aborted.
// I'm assuming that if we got here, the commit won't fail...
// But is it really true?
WebSecurity.CreateUserAndAccount("username", "123456");
tx.Commit();
}
不管怎麼說,基於上述代碼:
- 如果WebSecurity.CreateUserAndAccount失敗,整個事情失敗,預計。
- 如果任何SaveChanges方法失敗,那麼整個事情再次失敗,因爲我們沒有到達執行CreateUserAndAccount的點。
這整個事情給我一個問題: 它是否安全?我的意思是:
在我們成功執行DbContext.SaveChanges之後,「Commit」方法是否有可能拋出異常(以某種方式失敗)?如果發生這種情況,我們將以孤兒用戶最終結束,因爲提供者不是交易的一部分。
我很欣賞這方面的任何意見或建議。
快速注: 有這個漂亮的文章,解釋爲何我要投的DbContext到IObjectContextadapter而不是使用自己的連接屬性,但我無法找到它了。
感謝您的評論。是否可以共享EF和SimpleMembershipProvider之間的連接?在發佈問題之前,我尋找了一種方法來完成該任務,但找不到任何問題。至於其他選擇:我不認爲我可以在SQL Azure中使用分佈式事務,因此我正在爲此做好準備。 – CodeMaster2008
那麼,你當然可以傳遞一個開放的連接到'新的EntityConnection',然後把它傳遞給上下文構造器。我不確定你是否可以從SimpleMembershipProvider中提取連接(或傳遞一個連接),但它似乎應該有一種方法。 –
這將是完美的解決方案,但不幸的是我找不到一種方法來提取或傳遞連接到SimpleMembershipProvider,我開始相信這是不可能的。 – CodeMaster2008