当两个进程访问数据库时,NHibernate事务死锁

时间:2014-12-03 08:43:47

标签: sql-server nhibernate transactions deadlock

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

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

在事务中作为session.Save(obj)执行的插入。 对象id具有Guid类型,生成器类是" guid.comb"。

似乎之后NHibernate尝试处理这种情况,执行多次尝试插入行。在NHibernate sql日志文件中,我看到具有相同ID的同一个表中的INSERT语句数。

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

问题:

  1. 是否有可能防止我的情况出现僵局 NHibernate abilites?
  2. 是否可以防止NHibernate     执行几次尝试插入行并处理问题     我的代码(在NHibernate之外)?
  3. 提前致谢

1 个答案:

答案 0 :(得分:0)

当两个或多个进程都在等待访问另一个进程已经拥有的资源时,就会发生死锁。要防止死锁,您必须确保至少有一个进程始终能够继续。确保这一点的一个策略是订购你的锁。如果两个进程总是以相同的顺序获取锁,则不会发生死锁,因为如果进程成功获取第一个锁,则意味着第二个锁必须是空闲的(或者由不需要第一个锁的东西保持因此不需要等待释放锁定。)

实现这一目标的一种方法是让两个进程都获取表锁。您还可以分析SQL Server中的进程,以查找它们获取的锁以及它们正在等待的内容。

至于第二部分,我怀疑NHibernate本身是否正在重试INSERT语句。您是否遵循了立即回滚并丢弃发生异常的事务和NHibernate会话所需的做法?