【发布时间】:2016-03-01 17:06:33
【问题描述】:
首先,我不是多线程和并行编程方面的专家。
我正在尝试优化旧应用程序的性能(.Net 4、NHibernate 2.1)。
**到目前为止,升级NHibernate 不是优先事项,但正在筹备中。
随着时间的推移,随着数据的增长,性能已经成为一场噩梦。我见过的一个项目是 Parallel.ForEach 语句,它调用了一个获取和更新复杂实体(具有多个关系 - 属性和集合)的方法。
这段代码具有以下形式(为清楚起见进行了简化):
void SomeMethod(ICollection<TheClass> itemsToProcess)
{
Parallel.ForEach(itemsToProcess, item => ProcessItem(item);
}
TheClass ProcessItem(TheClass i)
{
var temp = NHibernateRepository.SomeFetchMethod(i);
var result = NHibernateRepository.Update(temp);
return result;
}
SQL Server 间歇性地报告数据库锁定错误,错误如下:
Transaction (Process ID 20) was deadlocked on lock resources with another process and has been chosen as the deadlock victim. Rerun the transaction
我怀疑这是由于某些竞争条件导致了死锁,即使 ISessions 是分开的。
ICollection<TheClass> 最多可以有 1000 个项目,每个项目都有要处理的属性和子集合,生成许多 SELECT 和 UPDATE 语句(使用“NHibernate Profiler”确认)
有没有更好的方法来并行处理这个问题,还是我应该将代码重构为传统循环?
我确实知道我可以使用以下方式实现我的代码:
-
foreach循环在同一ISession上下文中 - 使用无状态会话
-
Environment.BatchSize设置为合理的值
或
- 使用 SQL BulkCopy
我还阅读了很多关于 SQL Server 死锁和Parallel.ForEach 是一个简单的陷阱的好信息:
【问题讨论】:
标签: c# sql-server multithreading .net-4.0 nhibernate-4