首先,我不是多线程和并行编程方面的专家。
我正在尝试优化旧版应用程序 ( .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
是分开的。
最多可以有 1000 个项目,每个项目都有处理的ICollection<TheClass>
属性和子集合,生成许多SELECT
和UPDATE
语句(使用“NHibernate Profiler”确认)
有没有更好的方法以并行方式处理这个问题,或者我应该将代码重构为传统循环?
我知道我也可以使用以下方法实现我的代码:
foreach
同一ISession
上下文中的循环- 使用无状态会话
- 设置
Environment.BatchSize
为合理的值
或者
- 使用 SQL 批量复制
Parallel.ForEach
我还阅读了很多关于 SQL Server 死锁和容易陷入陷阱的好信息 :