当前位置: 首页 > 知识库问答 >
问题:

如何在 postgres 中设置锁定超时 - Hibernate

慕才
2023-03-14

我正在尝试为我正在处理的行设置锁定,直到下一次提交:

entityManager.createQuery("SELECT value from Table where id=:id")
            .setParameter("id", "123")
            .setLockMode(LockModeType.PESSIMISTIC_WRITE)
            .setHint("javax.persistence.lock.timeout", 10000)
            .getSingleResult();

我认为应该发生的是,如果两个线程同时尝试写入db,一个线程将在另一个线程之前到达更新操作,第二个线程应该等待10秒,然后抛出PessimisticLockExc的

但相反,线程挂起,直到另一个线程完成,无论设置的超时如何。

看看这个例子:

database.createTransaction(transaction -> {
    // Execute the first request to the db, and lock the table
    requestAndLock(transaction);

    // open another transaction, and execute the second request in
    // a different transaction
    database.createTransaction(secondTransaction -> {
        requestAndLock(secondTransaction);
    });

    transaction.commit();
});

我预期在第二个请求中,事务将等待超时设置,然后抛出PessimisticLockException,但它将永远死锁。

Hibernate通过以下方式生成我对数据库的请求:

SELECT value from Table where id=123 FOR UPDATE

在这个答案中,我看到<code>Postgres</code>只允许<code>SELECT FOR UPDATE NO WAIT</code>将超时设置为0,但不可能以这种方式设置超时。

还有其他方法可以与Hibernate / JPA一起使用吗?也许以某种方式推荐这种方式?

共有3个答案

骆文华
2023-03-14

这里有一个<code>lock_timeout</code>参数,它正是您想要的。

您可以在<code>postgresql中设置它。conf</code>或每个用户或每个数据库使用<code>ALTER ROLE</code>或<code<ALTER DATABASE</code>。

谢裕
2023-03-14

我认为你可以试试

SET LOCAL lock_timeout = '10s';
SELECT ....;

我怀疑Hibernate是否支持这一点。你可以尝试找到一种方法来扩展它,但不确定它是否值得。因为我想在postges数据库(即mvcc)上使用锁不是最明智的选择。

您也可以从代码中执行< code >无等待和延迟重试几次。

尉迟边浩
2023-03-14

Hibernate支持一系列查询提示。您使用的是设置查询超时,而不是悲观锁超时。查询和锁彼此独立,需要使用下面显示的提示。

但在此之前,请注意,Hibernate本身不处理超时。它只将其发送到数据库,并取决于数据库、是否以及如何应用它。

要为悲观锁设置超时,您需要使用<code>javax.persistence.lock。timeout</code>提示。下面是一个示例:

entityManager.createQuery("SELECT value from Table where id=:id")
        .setParameter("id", "123")
        .setLockMode(LockModeType.PESSIMISTIC_WRITE)
        .setHint("javax.persistence.lock.timeout", 10000)
        .getSingleResult();
 类似资料:
  • 问题内容: 有没有一种方法可以在Python中实现用于多线程目的的锁定,其方法可以具有任意超时?到目前为止,我发现的唯一可行的解​​决方案是使用轮询, 我发现优雅和低效 不保留锁的有界等待/进度保证作为关键部分问题的解决方案 有没有更好的方法来实现这一目标? 问题答案: 详细阐述史蒂文的评论建议: 注意事项: 有两个对象,一个在内部。 操作时,获取了锁;但是,该操作将其解锁,因此任何数量的线程都可

  • 问题内容: 我org.springframework.ws.client.core.WebServiceTemplate用于拨打Web服务。如何为通话配置超时。 问题答案: 如果你使用的是Spring Webservices 2.1.0版本,则可以使用HttpComponentsMessageSender设置超时。 Spring不推荐使用CommonsHttpMessageSender,因此不再推

  • 我正在尝试在我的WebClient上设置超时,以下是当前代码: 我需要添加超时和池策略,我在想这样的事情: 但是我不知道如何在我的webclient中设置httpClient

  • 问题内容: 我在我的应用程序中使用Retrofit库,我想将超时设置为60秒。改装有某种方法可以做到这一点吗? 我以这种方式设置Retrofit: 如何设置超时时间? 问题答案: 您可以在基础HTTP客户端上设置超时。如果未指定客户端,则Retrofit将使用默认的连接和读取超时创建一个客户端。要设置自己的超时时间,您需要配置自己的客户端并将其提供给。 一种选择是使用也是来自Square 的OkH

  • 但我想要的是这样的