【问题标题】:Good way to manage DataContext in ASP.NET? SqlException: Server failed to resume the transaction在 ASP.NET 中管理 DataContext 的好方法? SqlException:服务器无法恢复事务
【发布时间】:2011-08-29 13:58:04
【问题描述】:

我们使用以下类为每个请求创建一个 Linq2Sql DataContext:

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 6 上运行带有 SQL Server 2005 的 ASP .Net 2.0。

更新:

所以没有人会像我们一样犯同样可怕的错误:

事实证明,一些工作线程也使用了 DataContext,但没有 HttpContext 他们当然得到了 _staticContext(DataContextManager 中的一个功能,仅在测试时使用)。我们重写了工作线程中的代码,以确保每个线程有一个 DataContext 并在完成后处理它。到目前为止,一切都已经工作了 2 周:)

【问题讨论】:

标签: c# asp.net linq-to-sql


【解决方案1】:

这是一个糟糕的模式。首先,您永远不应该拥有它实现 IDisposable 的静态数据上下文,因此一个线程可以尝试使用该上下文,而另一个线程正在处理它以及许多其他潜在问题。每个 http 请求一个数据上下文也不好,数据上下文被设计为用于单个事务然后被处理掉。如果您检索更新/插入/删除并使用相同的上下文进行检索,则会出现问题,第二次检索不会反映更新/插入/删除的更改。删除静态上下文,只需让 Context 属性每次都返回一个新上下文。您仍然可以通过将它们全部粘贴在 List 属性中并遍历它来在请求结束时处理所有内容。

【讨论】:

  • 我对每个 HttpRequest 的 DataContext / ObjectContext 没有问题。单个页面请求中的操作通常是相关的,并且通常可以在单个上下文中完成。
  • 在大多数情况下它可以工作,但不是全部。如果您使用相关实体的集合执行检索和实体之类的操作,如果您从相关集合属性中添加或删除实体并保存到数据库,如果您再次检索实体,它不会获取更改。
猜你喜欢
  • 2015-12-19
  • 1970-01-01
  • 2014-07-08
  • 2011-04-23
  • 2010-11-26
  • 2014-03-06
  • 1970-01-01
  • 1970-01-01
  • 2014-11-09
相关资源
最近更新 更多