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

JPA悲观锁尝试从不超时

艾心远
2023-03-14

我试图在JPA中通过Hibernate3对Postgres数据库使用悲观锁定。我无法使锁超时--它似乎永远挂着。

这里有一个例子:

EntityManagerFactory factory; 

// (initialise the factory )

EntityManager em1 = factory.createEntityManager();
EntityManager em2 = factory.createEntityManager();

// em1 gets a lock

EntityTransaction transaction1 = em1.getTransaction();
transaction1.begin();
MyObject object1 = em1.find( MyObject.class, 1, LockModeType.PESSIMISTIC_READ );

// em2 tries for a lock

Map<String,Object> timeoutProperties = new HashMap<String,Object>();
timeoutProperties.put("javax.persistence.lock.timeout", 5000);

EntityTransaction transaction2 = em2.getTransaction();
transaction2.begin();
MyObject object2 = em2.find( MyObject.class, 1, LockModeType.PESSIMISTIC_READ, timeoutProperties );

// After five seconds I expect em2 to bail out, but it never does.

transaction1.rollback();
transaction2.rollback();

按照我的理解,em2应该尝试最多5秒(5000ms)来获得锁,然后应该抛出一个异常。相反,代码变成死锁。

谢谢,阿拉斯泰尔

共有1个答案

符功
2023-03-14

Postgres SELECT for update语法仅提供了在无法立即获得锁时不等待的选项。请参阅postgres文档。

若要防止操作等待其他事务提交,请使用NOWAIT选项。对于NOWAIT,如果无法立即锁定所选行,则语句将报告错误,而不是等待。注意,NOWAIT仅适用于行级锁-所需的行共享表级锁仍然以普通方式获得(参见第13章)。如果需要在不等待的情况下获取表级锁,则可以首先使用LOCK和NOWAIT选项。

在处理postgres时,我注意到任何超过0的超时值都将导致hibernate发出select for UPDATE,但当超时为0时,它将发出select for UPDATE NO wait

 类似资料:
  • 问题内容: 我正在尝试在JPA中使用悲观锁定,而不是针对Postgres数据库使用Hibernate 3。我无法超时锁定-它似乎永远挂着。 这是一个例子: 据我了解,em2应该尝试长达五秒钟(5000毫秒)来获取锁,然后应该抛出异常。而是代码陷入僵局。 如果我在两个不同的线程中运行它,那么我会看到线程2(带有em2)在线程1(em1)释放它后立即获得了锁。因此锁定正在发生,只是永不超时。 我用PE

  • 我正在使用Spring Boot、JPA、Oracle 12C和下面的类型化查询来选择要处理的“新”项目。一旦我选择了“新”项目,我就会更新其状态,使其不再符合选择条件,但我看到一个并发问题,相同的项目被选中。 我在这里读到,我需要设置一个'LockModeType.PESSIMISTIC_WRITE'的查询,以防止其他线程选择相同的行,但它似乎不起作用。 我是否遗漏了下面的内容,或者我是否需要另

  • 锁模式、和用于立即获得长期数据库锁。 我假设悲观的锁总是会触发数据库上的SQL,不管使用什么锁模式。现在有三个问题: 假设是否正确,或者如果正确,此规则是否有例外? 给定锁定了行。锁定行不能被任何其他事务更新,但锁定行的事务除外? 可以通过对事务执行提交或回滚来释放锁。如果应用程序(以及锁定行的事务)突然终止,而没有对事务执行提交或回滚,那么锁会发生什么情况?

  • 悲观锁:假定会发生并发冲突,屏蔽一切可能违反数据完整性的操作 乐观锁:假设不会发生并发冲突,只在提交操作时检查是否违反数据完整性。 乐观锁与悲观锁的具体区别: http://www.cnblogs.com/Bob-FD/p/3352216.html

  • 我使用的是Spring Boot 2和Spring数据JPA。 我有一个带有@Transactional annotation的服务,它从存储库中读取记录,如果记录不存在,则添加记录并保存所有记录。我创建了一个测试方法,并行执行服务方法5次。由于我使用的是@Lock(LockModeType.悲观写入),我希望其中一个线程在读取可用性时会得到锁,而其他4个线程必须等待事务(createReserv

  • Hibernate是我的JPA实现。