我有两个进程同时访问相同的数据库表。 两个进程都使用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约束。
问题:
提前致谢
答案 0 :(得分:0)
当两个或多个进程都在等待访问另一个进程已经拥有的资源时,就会发生死锁。要防止死锁,您必须确保至少有一个进程始终能够继续。确保这一点的一个策略是订购你的锁。如果两个进程总是以相同的顺序获取锁,则不会发生死锁,因为如果进程成功获取第一个锁,则意味着第二个锁必须是空闲的(或者由不需要第一个锁的东西保持因此不需要等待释放锁定。)
实现这一目标的一种方法是让两个进程都获取表锁。您还可以分析SQL Server中的进程,以查找它们获取的锁以及它们正在等待的内容。
至于第二部分,我怀疑NHibernate本身是否正在重试INSERT语句。您是否遵循了立即回滚并丢弃发生异常的事务和NHibernate会话所需的做法?