我想执行一个 SKIP LOCKED
使用 Spring Data JPA 在 Oracle 上查询,所以我尝试了以下操作:
@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
生成查询, 按要求。
最佳答案
你可以给 -2
超时值,以便尽可能使用“跳过锁定”。
PESSIMISTIC_WRITE with a javax.persistence.lock.timeout setting of -2
UPGRADE_SKIPLOCKED
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.
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
关于Spring 数据 JPA native 查询跳过锁定,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46208705/