In my application - Oracle with JPA (EclipseLink), I'm using the following expression to lock the subset of the records in some tables:
select * from MY_TABLE where MY_CONDITIONS for update skip locked
I run it throughout native query, but I have to write that query for all required entities.
Is there any way to skip locked records using pure JPA? Can I implement my own locking policy?
I don't mind changing JPA provider but I want to use JPA API.
In Oracle, FOR UPDATE SKIP LOCKED clause is usually used to select and process tasks from a queue by multiple concurrent sessions. It allows a session to query the queue table, skip rows currently locked by other sessions, select the next unlocked row, and lock it for processing.
Step 1: First read the account balance table using SELECT FOR UPDATE. Step 2: Check if there is sufficient balance for the withdrawal. If not abort. Step 3: Proceed to deduct the withdrawn amount from the balance and commit the transaction.
To specify a lock on a custom query method of a Spring Data JPA repository, we can annotate the method with @Lock and specify the required lock mode type: @Lock(LockModeType. OPTIMISTIC_FORCE_INCREMENT) @Query("SELECT c FROM Customer c WHERE c.
In order to use optimistic locking, we need to have an entity including a property with @Version annotation. While using it, each transaction that reads data holds the value of the version property. Before the transaction wants to make an update, it checks the version property again.
Hibernate provides the UPGRADE_SKIPLOCKED Lock mode.
Using JPA and Hibernate, to produce a "SKIP_LOCKED" as per Hibernate LockMode documentation, you have to combine the PESSIMISTIC_WRITE JPA LockModeType:
entityManager.find(Department.class, 1, LockModeType.PESSIMISTIC_WRITE);
and the Lock timeout setting, like for example in persistence.xml for your persistence unit:
<properties>
<property name="javax.persistence.query.timeout" value="-2"/>
</properties>
(Note that you can configure this LockMode for complex query as well)
SKIP LOCKED is not part of ANSI SQL. Some RDBMS such the following provide this as a specific feature:
So with pure JPA, it is not possible to specify a "SKIP LOCKED" in queries. Indeed, as documented in LockModeType, JPA 2.1 only supports the following:
However, to enable SKIP LOCKED in your query you can use these alternatives:
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