【问题标题】:"Server failed to resume the transaction" - Best practices using LINQ to Classes“服务器无法恢复事务” - 使用 LINQ to Classes 的最佳实践
【发布时间】:2011-06-20 19:36:06
【问题描述】:

使用 SQLSERVER 2008R2、VisualStudio 2010、.NET 4.0

我收到此定期异常:“服务器无法恢复事务 - Desc 2000003”(编号更改)

阅读在线论坛和此处,我发现主要原因是正确实例化并关闭连接。

我的课程应该是什么样的?

在 Class 级别创建 DataContext 并在所有方法上使用它?

public class BusProcess
{

    RENDBDataContext db = new RENDBDataContext();

    public void Insert()
    {
        //Do stuff here...
        db.InsertProcedure(...);
    }
 }

通过 using() 在每个方法上创建和处置一个新的 DataContext ?

public class BusProcess
{

    public void Insert()
    {
        using(RENDBDataContext db = new RENDBDataContext())
        {
            //Do stuff here...
            int sample = db.SomeObject.SingleOrDefault(...).Id;
            db.InsertProcedure(...);
        }
    }
 }

或者也许是不同的方法(最佳实践)

【问题讨论】:

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


    【解决方案1】:

    一般来说,DataContext 实例的生命周期应绑定到单个工作单元——您的第二次使用就是例证。

    第一次使用也可以,这取决于封闭类的寿命——但无论如何,确保类实现IDisposable,在你的@987654324实现中处理封闭的DataContext @,并用 using() 包装 that 类的用法。

    【讨论】:

    • 如果我使用第二个示例,并且假设该方法返回一个 IQueryable,那么我将无法使用该数据,因为 DataContext 已经被释放了?并且:为了处理 DataContext,只需将其变量设置为 null 就足够了吗?
    • @Vitor:你说得对,返回的IQueryable 会失败,但你可以实现查询(即调用ToListToArray)并返回它。对于实现IDisposable 的类来说,简单地将变量设置为null 是不够的:该接口的重点是在您完成实例后立即调用Dispose()(例如通过using)。否则,在 GC 收集对象(并调用其终结器)之前,不会清理其资源。
    【解决方案2】:

    第二种方法比一直使用 DataContext 更好。它会在调用 Load 等时防止内存消耗。还要记住连接是池化的,所以创建新的 DataContext 没什么大不了的。

    【讨论】:

      【解决方案3】:

      两者的结合。使用第一种方法,但让您的类实现 IDisposable 并在您的类 dispose 方法中的上下文上调用 dispose。然后,您可以在 using 语句中使用您的类。您还可以在类的构造函数中传入DataContext,以增加灵活性。

      【讨论】:

        猜你喜欢
        • 2010-11-26
        • 2018-09-25
        • 1970-01-01
        • 2016-11-09
        • 1970-01-01
        • 2010-12-31
        • 2015-07-26
        • 1970-01-01
        • 2010-12-21
        相关资源
        最近更新 更多