2011-08-29 199 views
1

我們創建一個LINQ2SQL的DataContext使用下面的類每一個請求:在ASP.NET中管理DataContext的好方法? SQLEXCEPTION:服務器無法恢復交易

public static class DataContextManager 
{ 

    private const string HTTPCONTEXT_KEY = "DataContextManagerKey"; 

    private static CompanyDataContext _staticContext; //when there's no HttpContext (in test/debug situations). 

    public static CompanyDataContext Context 
    { 
     get 
     { 
      if (_Context == null) 
      { 
       _Context = NewContext(); 
      } 
      return _Context; 
     } 
    } 

    private static CompanyDataContext _Context 
    { 
     get 
     { 
      return (CompanyDataContext)(HttpContext.Current != null ? HttpContext.Current.Items[HTTPCONTEXT_KEY] : _staticContext); 
     } 
     set 
     { 
      if (HttpContext.Current != null) 
      { 
       HttpContext.Current.Items[HTTPCONTEXT_KEY] = value; 
      } 
      else 
      { 
       DataContextManager._staticContext = value; 
      }  
     } 
    } 

    public static void Dispose() 
    { 
     CompanyDataContext context = _Context; 
     if (context != null) 
     { 
      if (Config.Instance.TestMode) context.Log.WriteLine("--- DISPOSING DATACONTEXT ---"); 
      context.Dispose(); 
      _Context = null; 
     } 
    } 

    public static CompanyDataContext NewContext() 
    { 
     CompanyDataContext db = new CompanyDataContext(); 
     db.CommandTimeout = Config.SQL_COMMAND_TIMEOUT; 
     if (Config.Instance.TestMode) 
     { 
      db.Log = new ConsoleTextWriter(); 
      db.Log.WriteLine("--- CREATING NEW DATACONTEXT ---"); 
     } 
     return db; 
    } 

} 

而且在Global.asax中:

protected void Application_EndRequest(Object sender, EventArgs e) 
{ 
    DataContextManager.Dispose(); 
} 

我之所以這麼問是我們突然變得隨機「SqlException:服務器無法恢復事務」例外,每天一次或兩次使用完美工作的代碼。在異常之後,我們會收到很多其他異常,直到我們重新啓動Web應用程序。任何人以前見過這種行爲?

我們在IIS上運行ASP.NET 2.0中使用SQL Server 2005 6.

UPDATE:

正是這樣沒有人不一樣可怕的錯誤,因爲我們沒有:

原來一些工作線程也使用了DataContext,但沒有HttpContext,他們當然得到了_staticContext(DataContextManager中的一個功能只在測試時使用)。我們重寫了工作線程中的代碼,以確保每個線程都有一個DataContext並在完成時處理它。到目前爲止,所有的東西都可以工作2周:)

+0

它似乎你的問題是有關http://stackoverflow.com/questions/1388599/periodic-invalidcastexception-and-the-server-failed-to-resume-the-transaction-w但沒有接受的答案那裏 –

+0

也有關:http://stackoverflow.com/questions/3927978/annoying-sql-exception-probably-due-to-some-code-done-wrong –

回答

0

這是一種不好的模式。首先,你永遠不應該有一個靜態數據上下文實現IDisposable,因此一個線程可以嘗試使用上下文,而另一個正在處理它加上許多其他潛在的問題。每個http請求一個數據上下文也不好,數據上下文被設計爲用於單個事務,然後處理。如果您使用相同的上下文檢索更新/插入/刪除和檢索,則會出現問題,第二次檢索不會反映更新/插入/刪除的更改。刪除靜態上下文,並讓Context屬性每次都返回一個新的上下文。您仍然可以在請求結束時處理所有請求,方法是將它們全部粘貼到List屬性中並遍歷它。

+1

我沒有問題,每個HttpRequest的DataContext/ObjectContext 。單個頁面請求中的操作通常是相關的,並且通常可以在單個上下文中完成。 –

+0

它可以在大多數情況下工作,但不是全部。如果您使用相關實體集合進行檢索和實體操作,如果您從相關集合屬性中添加或刪除實體並將其保存到數據庫中,則如果您再次檢索實體,則不會選取更改。 –

相關問題