并行线程中的多个数据库上下文,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资源。当活动用户较少时,请重新运行您的语句。请让数据库管理员检查此实例的锁和内存配置,或检查是否有长时间运行的事务。
有人知道是什么导致了这种情况,或者如何预防吗?谢谢
您也可以尝试使用new ParallelOptions { MaxDegreeOfParallelism = 8 }
在Parallel.ForEach()
方法中设置并发任务的最大数量(用您想要限制的任何值替换8)。
有关更多详细信息,请参阅MSDN。
您还应该了解为什么您的应用程序占用了如此大量的锁?您已经将TransactionScope封装在多个数据库连接周围。这可能会导致一个可能与之相关的分布式事务。它肯定会导致锁直到最后才被释放。改变这一点。
到目前为止,您只能打开锁定限制。它不会扩展到任意数量的供应商ID。您需要找到锁的原因,而不是减轻症状。
您正在运行sql server允许的最大锁数,默认情况下,该锁数是自动设置的,并由可用内存管理。
你可以
- 手动设置-我忘了怎么设置,但谷歌是你的朋友
- 为sql server添加更多内存
- 更频繁地提交交易