【问题标题】:Spring Data JPA + Hibernate Skip Locked rows (PostgreSQL)Spring Data JPA + Hibernate 跳过锁定行 (PostgreSQL)
【发布时间】:2019-02-03 02:38:18
【问题描述】:

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

生成的查询:

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

我错过了什么?

【问题讨论】:

  • 从那以后您找到解决问题的方法了吗? ^^'

标签: spring postgresql hibernate jpa


【解决方案1】:

您可以使用 nativeQuery。

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

【讨论】:

    【解决方案2】:

    您的代码很好。您需要记住的是 PESSIMISTIC_WRITE 在 Oracle 和 PostgreSQL 9.5 中使用 SELECT …​ FOR UPDATE SKIP LOCKED。我假设您可能已经忘记告诉 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
      
      显然,在事务完成之前,并发线程无法获取锁定的行。
    • 使用本机查询:
      SELECT * FROM objects o WHERE o.valid_until <= :validUntil FOR UPDATE SKIP LOCKED 
      

    【讨论】:

      猜你喜欢
      • 2016-06-26
      • 2017-07-17
      • 2019-07-20
      • 2016-10-15
      • 1970-01-01
      • 2014-02-12
      • 2018-02-22
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多