我的Project已经为hibernate 3.3.2.GA版本锁定了一个行机制,我们计划提升到hibernate 5.我打算让这个查询在更老的hibernate和更新版本中运行。
这是hibernate 3.3.2.GA中的现有查询
如果行已在会话中被锁定,此查询将锁定该行,将等到超时,如果超出则抛出超时。
Query query = session.getNamedQuery("select aps from WritableSchool aps where aps.schoolCd = :schoolCd");
query.setParameter("schoolCd", schoolCd);
query.setTimeout(2); // seconds
query.setLockMode("aps", LockMode.UPGRADE);
List<WritableSchool> schools = query.list();
当我们升级到hibernate 4/5版本时,超时工作无效,如果表已在会话中锁定,它将永远等待获取锁。
在使用相同代码的hibernate 4中,我尝试用这种方式替换锁定和超时
query.setLockOptions(new LockOptions(LockMode.UPGRADE).setTimeOut(100));
它仍然无法让时间停止工作。
我也试过了另一种方式。
session.buildLockRequest(LockOptions.NONE).setLockMode(LockMode.UPGRADE).setTimeOut(2000).lock(school);
正在执行select ..进行更新,但是没有遵守我执行的时间。
目前我手中唯一的解决方案是覆盖hibernate oracle方言并将shouldUseFollowOnLocking()
设置为false,同时获得锁定和荣誉超时。
我想知道为什么hibernate对Lockoptions的超时时间不同。如果任何人对锁定有任何想法并且在休眠状态下超时,请帮助,谢谢。
答案 0 :(得分:0)
在尝试了一些可能的方法后,我发现这种方式,我们可以设置锁定与hibernate 3.5.6兼容的超时与当前的hibernate版本没有任何问题。
Session session = ((Session) em.getDelegate());
Query query = session.getNamedQuery("select aps from WritableSchool aps where aps.schoolCd = :schoolCd"); query.setParameter("schoolCd", schoolCd);
WritableSchool schools = query.list().get(0);
session.buildLockRequest(LockOptions.NONE).setLockMode(LockMode.PESSIMISTIC_WRITE).setTimeOut(2000).lock(aliasPoolSeq);
第二种方式,但这适用于3.5.6和所有其他更高版本。
school = (WritableSchool ) session.get(WritableSchool .class, primaryKey,
new LockOptions(LockMode.PESSIMISTIC_WRITE).setTimeOut(QUERY_TIMEOUT_SEC * 1000))
答案 1 :(得分:0)
如果你允许在你的项目中扩展hibernate方言,我找到了替代解决方案,它适用于不同的hibernate版本。你可以用这种方式覆盖
public class Oracle10gDialectExtension extends Oracle10gDialect implements DialectExtension
{
@Override
public boolean useFollowOnLocking()
{
return false;
}
}