2014-12-03 76 views
0

我有两个进程同时访问相同的数据库表。 这两个进程都使用NHibernate-3.2.0。 一个进程删除行,另一个进程将行插入到相同的表中。 当两个进程并行工作时,我在“INSERT”进程中收到死锁错误。当两个进程访问数据库时NHibernate事务死锁

[错误] TID:6 NHibernate.Util.ADOExceptionReporter - 事务(进程ID 64)在另一个进程锁死资源上死锁,并被选为死锁牺牲品。重新运行交易。

该插入在事务内部执行为session.Save(obj)。 对象ID有Guid类型,生成器类是“guid.comb”。

看起来好像NHibernate试图处理这种情况,执行多次插入行的尝试。在NHibernate sql日志文件中,我看到与同一个ID相同的表的INSERT语句的数量。

而下面是下一个错误: [错误] TID:6 Hibernate.Util.ADOExceptionReporter - 违反PRIMARY KEY约束。

问题:

  1. 是否有可能阻止我scenarion死锁情况由 NHibernate的别的技能?
  2. 可以防止从NHibernate到 执行多行尝试插入行处理问题我的代码(NHibernate外部) ?

在此先感谢,当两个或多个进程都在等待访问已被其他进程持有资源发生

+0

这两个进程是否使用相同的NHSession?你在使用交易吗?你什么时候提交或冲洗? – 2014-12-03 14:03:47

回答

0

死锁。为防止死锁,您必须确保至少有一个进程始终能够继续。确保这一点的一个策略是订购你的锁。如果两个进程始终以相同的顺序获取锁,则不会发生死锁,因为如果进程成功获取第一个锁,则意味着第二个锁必须是空闲的(或由某些不需要第一个锁的锁保留)不需要等待该锁被释放)。

实现这一目标的一种方法是让这两个进程都获取表锁。您还可以分析SQL服务器中的进程以查找他们获取的锁以及他们正在等待的内容。至于第二部分,我怀疑NHibernate本身是否正在重试INSERT语句。您是否遵循了立即回滚并放弃发生异常的事务和NHibernate会话的所需做法?