【问题标题】:Spring data JPA native query skip lockedSpring数据JPA本机查询跳过锁定
【发布时间】:2018-02-22 19:46:43
【问题描述】:

我想使用 Spring Data JPA 在 Oracle 上执行 SKIP LOCKED 查询,所以我尝试了以下方法:

@Lock(LockModeType.PESSIMISTIC_WRITE)
@Query(value = "SELECT * FROM User WHERE ID=?1 FOR UPDATE SKIP LOCKED", nativeQuery = true)
User findOne(UUID id);

我尝试了上面的,发现生成的查询包含FOR UPDATE,但不包含SKIP LOCKED(下面是从日志中生成的查询):

select ent0_.column1 as name, ent0_.CREATED_DATE as CREATED_2_33_0_ from TABLE_NAME alias_name where ent0_.column1=? for update

如果我从查询方法中删除@Lock,生成的查询甚至没有FOR UPDATE

请根据需要建议我如何使用FOR UPDATE SKIP LOCKED 生成查询。

【问题讨论】:

  • 如您所见,FOR UPDATE 是由 @Lock(LockModeType.PESSIMISTIC_WRITE) 添加的,而不是您的本机查询。由于 JPA 是一个与数据库无关的规范,不幸的是,这只是 JPA 所能达到的范围,因为 SKIP LOCKED 是 Oracle 特定的特性。如果您必须使用特定于数据库的功能,则必须编写一个自定义存储库实现,直接通过 EntityManager 执行原始 SQL。

标签: spring hibernate jpa spring-data-jpa


【解决方案1】:

您可以将-2 设置为超时值,以便尽可能使用“跳过锁定”。

PESSIMISTIC_WRITE 的 javax.persistence.lock.timeout 设置为 -2

UPGRADE_SKIPLOCKED

锁获取请求会跳过已经锁定的行。它使用一个 SELECT …​ FOR UPDATE SKIP LOCKED 在 Oracle 和 PostgreSQL 9.5 中,或 SELECT ...​ 在 SQL Server 中使用 (rowlock, updlock, readpast)。

public interface MyRepository extends CrudRepository<MyEntity, Long> {

    /**
     * The lock acquisition request skips the already locked rows.
     * It uses a SELECT …​ FOR UPDATE SKIP LOCKED in Oracle and PostgreSQL 9.5,
     * or SELECT …​ with (rowlock, updlock, readpast) in SQL Server.
     */
    String UPGRADE_SKIPLOCKED = "-2";

    @Lock(value = LockModeType.PESSIMISTIC_WRITE) // adds 'FOR UPDATE' statement
    @QueryHints({@QueryHint(name = "javax.persistence.lock.timeout", value = UPGRADE_SKIPLOCKED)})
    MyEntity findFirstByStatus(String status);

}

通过这样做,选择查询将具有select ... for update skip locked

https://docs.jboss.org/hibernate/orm/5.0/userguide/html_single/chapters/locking/Locking.html

【讨论】:

    【解决方案2】:

    添加:

    @QueryHints({@QueryHint(name = "javax.persistence.lock.timeout", 值 ="-2")})

    【讨论】:

      猜你喜欢
      • 2019-02-03
      • 2017-11-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-10-01
      • 2020-08-04
      • 2018-06-27
      • 1970-01-01
      相关资源
      最近更新 更多