从JPA级别选择更新跳过锁定

在我的应用程序 – 带JPA的Oracle(EclipseLink)中,我使用以下表达式来锁定某些表中的记录子集:

select * from MY_TABLE where MY_CONDITIONS for update skip locked 

我在本机查询中运行它,但我必须为所有必需的实体编写该查询。

有没有办法使用纯JPA跳过锁定的记录? 我可以实施自己的锁定政策吗?

我不介意更改JPA提供程序,但我想使用JPA API。

Hibernate提供UPGRADE_SKIPLOCKED锁定模式。

使用JPA和Hibernate,根据Hibernate LockMode文档生成“SKIP_LOCKED”,您必须组合PESSIMISTIC_WRITE JPA LockModeType :

 entityManager.find(Department.class, 1, LockModeType.PESSIMISTIC_WRITE); 

和锁定超时设置,例如在持久性单元的persistence.xml中:

    

(请注意,您也可以为复杂查询配置此LockMode)

SKIP LOCKED不是ANSI SQL的一部分。 以下一些RDBMS将此作为特定function提供:

  • MySQL的
  • PostgreSQL的
  • 神谕

因此,对于纯JPA,无法在查询中指定“SKIP LOCKED”。 实际上,正如LockModeType中所述 ,JPA 2.1仅支持以下内容:

  • 没有
  • OPTIMISTIC
  • OPTIMISTIC_FORCE_INCREMENT
  • PESSIMISTIC_FORCE_INCREMENT
  • PESSIMISTIC_READ
  • PESSIMISTIC_WRITE

但是,要在查询中启用SKIP LOCKED,您可以使用以下替代方法:

  • 使用特定的JPA实现function,例如Hibernate LockMode ,它允许通过JPA查询指定SKIP LOCKED,这要归功于如上所述的PESSIMISTIC_WRITE LockModeType Lock Timeout特定设置的组合
  • 像您一样创建本机SQL查询

Oracle不提供读锁定,因为它不需要读锁定; 撤消日志使其不必要。 因此,SELECT … FOR UPDATE实际上只是Oracle的WRITE锁。

使用JPA,您希望将LockModeType设置为PESSIMISTIC_WRITE。