我正在尝试使用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 locked和Select 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 _
我想念什么?
答案 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();