Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/hibernate/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Hibernate 带Postgres的Spring数据悲观锁超时_Hibernate_Postgresql_Jpa_Spring Data - Fatal编程技术网

Hibernate 带Postgres的Spring数据悲观锁超时

Hibernate 带Postgres的Spring数据悲观锁超时,hibernate,postgresql,jpa,spring-data,Hibernate,Postgresql,Jpa,Spring Data,我在获取Spring数据以发送postgres以更新NOWAIT时失败 我在存储库中尝试了以下方法: @Lock(value = LockModeType.PESSIMISTIC_WRITE) MyObject findByUuid(String uuid); 配置(代码段) 我甚至在我的服务中注入EntityManager,这将返回0: info(em.getProperties().get(“javax.persistence.lock.timeout”) 但是上面只给了我“更新”,NOW

我在获取Spring数据以发送postgres以更新NOWAIT时失败

我在存储库中尝试了以下方法:

@Lock(value = LockModeType.PESSIMISTIC_WRITE)
MyObject findByUuid(String uuid);
配置(代码段)

我甚至在我的服务中注入EntityManager,这将返回0:

info(em.getProperties().get(“javax.persistence.lock.timeout”)

但是上面只给了我“更新”,NOWAIT部分没有被设置。我是否设置了正确的东西(从另一篇文章来看,这应该是可行的)

这让我更接近,尽管我不喜欢使用原始sql

 @Lock(value = LockModeType.PESSIMISTIC_WRITE)
 @Query(value = "SELECT * FROM the_table WHERE uuid = :uuid FOR UPDATE NOWAIT", nativeQuery = true)
 MyObject findByUuid(@Param("uuid") String uuid);
这确实给了我一个锁异常,但是Spring修饰的服务(代理)在返回时抛出一个事务/回滚异常,这意味着我不能在方法上给出我需要的返回值

问题: 1) 如何获取Spring数据以添加NOWAIT? 2) 是否有方法返回值?我怀疑我需要自己处理事务,或者更改逻辑流?不确定Spring是否处理NOWAIT,它是否会有不同的行为

我意识到也有类似的问题,但这略有不同。
我使用的是hibernate 4.2.15,spring数据jpa 1.7.1,postgres sql 9.3。

使用悲观的强制增量

javax.persistence.lock.timeout在如下提供的情况下对我也不起作用

@QueryHints({@QueryHint(name = "javax.persistence.lock.timeout",value = "15000")})
但后来我尝试了其他有效的方法。现在,我不再使用@Repository和crudepository,而是使用实体管理器配置我的hibernate。使用createQuery以及锁定和设置锁定超时。此配置正在按预期工作。我有两个并行运行的事务,试图在DB中锁定完全相同的行。第一个事务能够获取写锁,并在释放锁之前保持锁大约10秒。同时,第二个事务尝试获取同一行上的锁,但由于javax.persistence.lock.timeout设置为15秒,因此它等待释放锁,然后获取自己的锁。因此使流序列化

@Component
public class Repository {

    @PersistenceContext
    private EntityManager em;

    public Optional<Cache> getById(int id){
        List<Cache> list = em.createQuery("select c from Cache c where c.id = ?1")
                            .setParameter(1, id)
                            .setHint("javax.persistence.lock.timeout", 15000)
                            .setLockMode(LockModeType.PESSIMISTIC_WRITE)
                            .getResultList();


        return Optional.ofNullable(list.get(0));
    }

    public void save(Cache cache) {
        cache = em.find(Cache.class, cache.getId());
        em.merge(cache);
    }
}
@组件
公共类存储库{
@持久上下文
私人实体管理者;
公共可选getById(int-id){
List List=em.createQuery(“从缓存c中选择c,其中c.id=?1”)
.setParameter(1,id)
.setHint(“javax.persistence.lock.timeout”,15000)
.setLockMode(LockModeType.悲观写入)
.getResultList();
返回可选的.ofNullable(list.get(0));
}
公共无效保存(缓存){
cache=em.find(cache.class,cache.getId());
em.merge(缓存);
}
}

确保此锁机制位于事务内部,因为在提交或回滚事务时,锁将被释放

SpringDataJPA不会向Postgresql发送任何内容,您的JPA提供商会发送。Hibernate(您可能正在使用的)支持添加NOWAIT吗?好问题。看看我们使用的类(PostgressQL82方言),它有以下实现:getForUpdateNowaitString(…){返回这个。getForUpdateString(…)+“nowait”}基于HH-6452,应该这样做,这是唯一要检查的吗?然而,方言没有设置正确,所以它不工作,现在它是。这就解决了这个问题,谢谢@NeilStockton。虽然这个代码片段可以解决这个问题,但它确实有助于提高您文章的质量。请记住,您将在将来回答读者的问题,这些人可能不知道您的代码建议的原因。还请尽量不要用解释性注释挤满你的代码,这会降低代码和解释的可读性!不知为什么,这确实有帮助
@Component
public class Repository {

    @PersistenceContext
    private EntityManager em;

    public Optional<Cache> getById(int id){
        List<Cache> list = em.createQuery("select c from Cache c where c.id = ?1")
                            .setParameter(1, id)
                            .setHint("javax.persistence.lock.timeout", 15000)
                            .setLockMode(LockModeType.PESSIMISTIC_WRITE)
                            .getResultList();


        return Optional.ofNullable(list.get(0));
    }

    public void save(Cache cache) {
        cache = em.find(Cache.class, cache.getId());
        em.merge(cache);
    }
}