9

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资源。当活动用户较少时重新运行您的语句。请数据库管理员检查此实例的锁和内存配置,或检查是否长时间运行交易。”

有谁知道是什么原因造成的或如何预防?谢谢。

4

3 回答 3

6

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

有关详细信息,请参阅MSDN

于 2013-02-14T11:59:39.913 回答
1

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

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

于 2013-02-14T10:57:59.777 回答
0

您正在运行 sql server 允许的最大锁数 - 默认情况下自动设置并由可用内存控制。

你可以

  1. 手动设置 - 我完全忘记了,但谷歌是你的朋友。
  2. 为您的 sql server 添加更多内存
  3. 更频繁地提交您的交易。
于 2013-02-14T10:53:19.637 回答