我正在尝试使用 Spring Data JPA (2.1) 和 Hibernate 在 PostgreSQL 上执行 SKIP LOCKED 查询。查询如下所示:

@Lock(LockModeType.PESSIMISTIC_WRITE)
@QueryHints({@QueryHint(name = "javax.persistence.lock.timeout", value ="-2")})
List<Obj> findByEntityAndStatus(Entity entity, Status status);

根据 Spring data JPA native query skip lockedSelect for update skip locked from JPA level 它应该可以工作,但生成的查询只选择更新而不跳过锁定的行。

生成的查询:



我错过了什么?

最佳答案

你的代码没问题。您只需要记住 PESSIMISTIC_WRITE 使用 Oracle 中的 SELECT …​ FOR UPDATE SKIP LOCKED PostgreSQL 9.5 。我假设您可能已经忘记告诉 JPA,您应该使用较新版本的 Postgres。所以你有两个选择:

  • 告诉 JPA 您正在使用支持 SKIP LOCKED 的 PostgreSQL 方言:
    spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQL10Dialect
    

    在此之后,我收到了所需的输出:
    where
        subscripti0_.valid_until<=?
    and subscripti0_.status='ACTIVE'
    for update of subscripti0_1_ skip locked
    

    显然,在事务完成之前,并发线程无法获取锁定的行。
  • 使用 native 查询:
    SELECT * FROM objects o WHERE o.valid_until <= :validUntil FOR UPDATE SKIP LOCKED
    
  • 关于Spring Data JPA + Hibernate Skip Locked rows (PostgreSQL),我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/52058253/

    10-11 04:10