0

我正在將asp.net成員資格升級爲MVC4中新的簡單成員提供程序。這是一個Azure/Sql Azure應用程序,它可以在本地主機上正常運行,但在部署時會失敗。我有代碼的交易如下:Simplerole提供程序導致事務處理範圍內的遠程事務

  TransactionOptions toptions = new TransactionOptions(); 
      toptions.IsolationLevel = System.Transactions.IsolationLevel.Serializable; 
      using (TransactionScope trans = new TransactionScope(TransactionScopeOption.Required, toptions)) 
      { 
       try 
       { 
        ... do a bunch of database stuff in a single dbContext ... 

        var roleprov = (SimpleRoleProvider)Roles.Provider; 
        string[] roles = roleprov.GetRolesForUser(Username); 
        // above line fails with The transaction manager has disabled its support for remote/network transactions. (Exception from HRESULT: 0x8004D024) 
       } 
      } 

我使用this technique填充角色類。堆棧跟蹤似乎表明它確實試圖啓動一個子事務來完成該調用。 simplemembership表在不同的數據庫中。如何從單獨事務的上下文中的角色提供者獲取角色信息?

回答

0

問題是GetRolesForUser會導致新的連接打開到第二個數據庫,然後又會得到它在TransactionScope中。反過來這(MSDN - System.Transactions Integration with SQL Server)然後促進到DTC。你可以嘗試以下幾種選擇:

獲取交易之前角色開始

你可以檢索string[] rolesTransactionScope。你是否有理由讓它們進入範圍?既然你說:

我如何可以檢索從一個單獨的事務的上下文中的角色提供角色信息

這聽起來像你能拿TransactionScope之前的角色信息,並沒有任何問題。

關閉交易了簡單的會員連接字符串

你可以告訴一個連接字符串不參與交易通過將「爭取=假」(見SqlConnection.ConnectionString)在連接字符串中,所以這可能如果您從不需要使用簡單成員資格數據庫的事務處理,那麼您可以選擇一個選項。

嘗試打開該交易

之前簡單會員連接對於 SimpleRoleProvider它創建它的數據庫對象,然後打開它,它使用它的第一次。但是,它不會在...... 之前關閉它。 從頭開始,每次打到GetRolesForUser時都會打開連接,所以你運氣不好。我想你可以在TransactionScope打開之前調用GetRolesForUser一次,然後再次使用已經打開的連接在範圍內 - 你不能。

播放與IObjectContextAdapter

免責聲明:我不能保證這會工作,我不能與你的設置進行測試。

您可以使用技巧來阻止使用兩個連接字符串進行提升,方法是先在事務範圍外打開非事務連接字符串,然後不應提升事務。如果您在同一個事務處理範圍內(否則會導致升級)導致與CloseOpen的連接相同,也可以使用此功能。

您可以嘗試與您的上下文,並查看是否停止GetRolesForUser促進交易,但我懷疑這將工作,因爲GetRolesForUser導致連接打開,如果它尚未。由於我無法在您的場景中進行測試,因此我會將其納入以防萬一。

using (var db = new ExampleContext()) 
{ 
    var adapter = db as System.Data.Entity.Infrastructure.IObjectContextAdapter; 
    using (var conn = adapter.ObjectContext.Connection) 
    { 
     conn.Open(); 
     using (TransactionScope scope = new TransactionScope(TransactionScopeOption.Required)) 
     { 
      // perform operations 
      db.SaveChanges(); 
      // perform more operations 
      db.SaveChanges(); 
      // perform even more operations 
      db.SaveChanges(); 

      // If you don't complete, the transaction won't commit and you will lose the changes 
      scope.Complete(); 
     } 
    } 
} 
+0

最後,我找到了一種方法將角色從事務處理中取出。這有點尷尬,但它工作。我在這裏發現了一篇關於該問題的文章(http://social.technet.microsoft.com/wiki/contents/articles/handling-transactions-in-sql-azure.aspx) – AldenG

+0

@AldenG。是的,所以(「_當你有多個連接到不同的數據庫._)證實了我上面所說的。最後是否使用'SqlTransaction'而不是?我留下了該選項,因爲我認爲你需要堅持使用Roles和DbContext以減少與數據庫的耦合 –

+0

我使用SqlTransaction玩了一個小時,並找不到一種方式使它與實體框架很好地協作,將它從事務處理器中拉出來最終獲得了最簡單的解決方案,並且使用了一對擴展方法要訪問角色,代碼結束了足夠乾淨。感謝您的幫助。 – AldenG

相關問題