2012-09-07 16 views
4

首先使用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而不是使用自己的連接屬性,但我無法找到它了。

回答

2

是的,Commit肯定會丟。一個微不足道的例子是,如果連接下降。當然還有其他的情況。

您有幾種選擇:

  • 交易在同一個數據庫,如果連接共享將無法升級到分發。因此,您可以使用一個連接同時連接EF和您的WebSecurity連接。
  • 啓動服務器上的分佈式事務控制器並處於升級狀態。不是世界上最糟糕的事情。
  • 不是使用事務,而是改變操作的順序,以便部分成功的操作可以稍後完成或撤消。例如,檢測並清理「孤兒」用戶。
+0

感謝您的評論。是否可以共享EF和SimpleMembershipProvider之間的連接?在發佈問題之前,我尋找了一種方法來完成該任務,但找不到任何問題。至於其他選擇:我不認爲我可以在SQL Azure中使用分佈式事務,因此我正在爲此做好準備。 – CodeMaster2008

+0

那麼,你當然可以傳遞一個開放的連接到'新的EntityConnection',然後把它傳遞給上下文構造器。我不確定你是否可以從SimpleMembershipProvider中提取連接(或傳遞一個連接),但它似乎應該有一種方法。 –

+0

這將是完美的解決方案,但不幸的是我找不到一種方法來提取或傳遞連接到SimpleMembershipProvider,我開始相信這是不可能的。 – CodeMaster2008

相關問題