Spring Data JPA + Hibernate跳过锁定行(PostgreSQL)

时间:2018-08-28 12:44:10

标签: spring postgresql hibernate jpa

我正在尝试使用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,它应该可以工作,但是生成的查询仅选择更新而不跳过锁定的行。

生成的查询:

  

休眠:从objs obj0_左边外部连接实体enter1_上选择obj0_.id作为id1_5_,obj0_.name作为名称6_5_,obj0_.entity_id作为enterity10_5_,obj0_.status作为status8_5_,其中obj0_.entity_id = entity1_.id ?和obj0_.status =?用于更新obj0 _

我想念什么?

2 个答案:

答案 0 :(得分:1)

您的代码很好。您只需要记住,PESSIMISTIC_WRITE在Oracle和 PostgreSQL 9.5 中使用了SELECT …​ FOR UPDATE SKIP LOCKED。我想您可能已经忘记告诉JPA,您应该使用什么新版本的Postgres。因此,您有两种选择:

  • 告诉您您正在使用支持SKIP LOCKED的PostgreSQL方言的JPA:
    spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQL10Dialect
    
    在此之后,我收到了所需的输出:
    where
        subscripti0_.valid_until<=? 
    and subscripti0_.status='ACTIVE' 
    for update of subscripti0_1_ skip locked
    
    显然,并发线程在事务完成之前无法获取锁定的行。
  • 使用本机查询:
    SELECT * FROM objects o WHERE o.valid_until <= :validUntil FOR UPDATE SKIP LOCKED 
    

答案 1 :(得分:0)

您可以使用nativeQuery。

@Query(value = "SELECT * FROM task LIMIT 10 FOR UPDATE SKIP LOCKED", nativeQuery = true)
List<TaskEntity> fetchAllUnlocked();