I want to execute a SKIP LOCKED
query on Oracle using Spring Data JPA, so I tried the following:
@Lock(LockModeType.PESSIMISTIC_WRITE)
@Query(value = "SELECT * FROM User WHERE ID=?1 FOR UPDATE SKIP LOCKED", nativeQuery = true)
User findOne(UUID id);
I tried the above and found that the generated query contains FOR UPDATE
, but not SKIP LOCKED
(below is the generated query from logs):
select ent0_.column1 as name, ent0_.CREATED_DATE as CREATED_2_33_0_ from TABLE_NAME alias_name where ent0_.column1=? for update
If I remove @Lock
from the query method, the generated query does not even have FOR UPDATE
.
Please suggest how I can generate a query with FOR UPDATE SKIP LOCKED
, as required.
The OptimisticLockType. NONE disables the default optimistic locking mechanism for the TestEntity . However, that would only be useful if you inherited the @Version property from a base class which is annotated with @MappedSuperclass or @Inheritance .
The SKIP LOCKED DATA option allows a transaction to skip rows that are incompatibly locked by other transactions when those locks would hinder the progress of the transaction. Because the SKIP LOCKED DATA option skips these rows, the performance of some applications can be improved by eliminating lock wait time.
The SKIP LOCKED clause improves the scalability of applications that attempt to concurrently update the same set of rows in a table. It eliminates wait time for TX locks. Consistency and isolation are preserved.
PessimisticLockException indicates that obtaining a lock or converting a shared to exclusive lock fails and results in a transaction-level rollback. LockTimeoutException indicates that obtaining a lock or converting a shared lock to exclusive times out and results in a statement-level rollback.
You can assing -2
to timeout value so that 'skip locked' will be used whenever possible.
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);
}
By doing like this, the select query will have select ... for update skip locked
https://docs.jboss.org/hibernate/orm/5.0/userguide/html_single/chapters/locking/Locking.html
Add:
@QueryHints({@QueryHint(name = "javax.persistence.lock.timeout", value ="-2")})
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With