并行线程中的多个数据库上下文,EntityException“;当活动用户较少时重新运行您的语句“;

本文关键字:用户 活动 语句 重新运行 线程 数据库 上下文 并行 EntityException | 更新日期: 2023-09-27 17:59:00

我使用Parallel.ForEach在多个线程上进行工作,每次迭代都使用新的EF5 DbContext,所有这些都封装在TransactionScope中,如下所示:

using (var transaction = new TransactionScope())
{
    int[] supplierIds;
    using (var appContext = new AppContext())
    {
        supplierIds = appContext.Suppliers.Select(s => s.Id).ToArray();
    }
    Parallel.ForEach(
        supplierIds,
        supplierId =>
    {
        using (var appContext = new AppContext())
        {
            Do some work...
            appContext.SaveChanges();                
        }
    });
    transaction.Complete();
}

运行几分钟后,它抛出EntityException"基础提供程序在打开时失败",并包含以下内部详细信息:

SQL Server数据库引擎的实例此时无法获得LOCK资源。当活动用户较少时,请重新运行您的语句。请让数据库管理员检查此实例的锁和内存配置,或检查是否有长时间运行的事务。

有人知道是什么导致了这种情况,或者如何预防吗?谢谢

并行线程中的多个数据库上下文,EntityException“;当活动用户较少时重新运行您的语句“;

您也可以尝试使用new ParallelOptions { MaxDegreeOfParallelism = 8 }Parallel.ForEach()方法中设置并发任务的最大数量(用您想要限制的任何值替换8)。

有关更多详细信息,请参阅MSDN。

您还应该了解为什么您的应用程序占用了如此大量的锁?您已经将TransactionScope封装在多个数据库连接周围。这可能会导致一个可能与之相关的分布式事务。它肯定会导致锁直到最后才被释放。改变这一点。

到目前为止,您只能打开锁定限制。它不会扩展到任意数量的供应商ID。您需要找到锁的原因,而不是减轻症状。

您正在运行sql server允许的最大锁数,默认情况下,该锁数是自动设置的,并由可用内存管理。

你可以

  1. 手动设置-我忘了怎么设置,但谷歌是你的朋友
  2. 为sql server添加更多内存
  3. 更频繁地提交交易