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

Jan*_*nar 6 postgresql spring 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);
Run Code Online (Sandbox Code Playgroud)

根据Spring data JPA native queryskiplockedSelect for updateskiplocked from JPA level它应该可以工作,但生成的查询仅选择更新而不跳过锁定的行。

生成的查询:

休眠:从objs obj0_左外连接实体entity1_上选择obj0_.id作为id1_5_,obj0_.name作为name6_5_,obj0_.entity_id作为entity10_5_,obj0_.status作为status8_5_,在obj0_.entity_id=entity1_.id上,其中entity1_.id=?和 obj0_.status=?用于更新 obj0_

我缺少什么?

J.W*_*icz 6

你的代码没问题。您需要记住的是 PESSIMISTIC_WRITESELECT \xe2\x80\xa6\xe2\x80\x8b FOR UPDATE SKIP LOCKED在 Oracle 和PostgreSQL 9.5中使用 a 。我假设您可能忘记告诉 JPA 您要使用新版本的 Postgres。所以你有两个选择:

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


小智 0

您可以使用nativeQuery。

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