使用Hibernate和DB2(以及Derby)进行悲观锁定?

时间:2011-10-24 15:32:29

标签: hibernate spring locking db2

拥有以下代码:

@Transactional // Spring annotation
public void doStuffWithPayments(...) {
  List payments = getCurrentSession().createQuery("select distinct p from Payment p .....")
      .setLockMode("p", LockMode.UPGRADE)
      .list();
  do_stuff(); // Takes an extended amount of time
  updatePayments(payments);
}

...生成如:

的sql
select ...... from Payment where .....  for read only with rs

两个并发线程进入尝试访问同一db记录的方法。线程1在线程2之前进入短时间。我希望线程2被强制等待“.list()”,直到线程1离开事务范围并且事务被提交。

这可能吗?

编辑(评论后): 试图

@Transactional(isolation = Isolation.SERIALIZABLE)

但两个线程仍然通过db读操作。

在最后的数据库写入时,数据库中出现死锁。

EDIT2 我使用Derby获得相同的行为。

还尝试按照建议设置锁定:

getCurrentSession().refresh(object, LockMode.UPGRADE);

线程2仍然通过并从db ...

读取对象

3 个答案:

答案 0 :(得分:1)

这就是我锁定对象的方法:

if (object != null && getSession().getCurrentLockMode(object) != LockMode.UPGRADE) {
    getSession().refresh(object, LockMode.UPGRADE);
}

SERIALIZABLE隔离级别是最高级别的隔离,而且非常昂贵,因为所有事务都将按顺序执行。因此,在使用之前,您需要确保确实需要它。

答案 1 :(得分:0)

尝试将isolation=SERIALIZABLE添加到注释中。

答案 2 :(得分:0)

见这里:

https://forum.hibernate.org/viewtopic.php?p=2356502

它建议继承DerbyDialect并重写getForUpdateString()方法。

这适用于我,虽然有旧版本的Hibernate(3.3.2.GA)。