拥有以下代码:
@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);
}
...生成如:
的sqlselect ...... 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 ...
读取对象答案 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)。