超时

时间:2017-04-20 22:23:22

标签: java hibernate

我的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的超时时间不同。如果任何人对锁定有任何想法并且在休眠状态下超时,请帮助,谢谢。

2 个答案:

答案 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;
    }
}