Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Select for update skip locked from JPA level

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.

like image 381
Dominik Kunicki Avatar asked Jan 02 '17 22:01

Dominik Kunicki


People also ask

What is for update skip locked?

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.

How do I select a JPA update?

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.

How do you do specific locking in Spring JPA?

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.

How do you implement optimistic locking in JPA?

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.


1 Answers

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:

  • MySQL
  • Postgresql
  • Oracle

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:

  • NONE
  • OPTIMISTIC
  • OPTIMISTIC_FORCE_INCREMENT
  • PESSIMISTIC_FORCE_INCREMENT
  • PESSIMISTIC_READ
  • PESSIMISTIC_WRITE
  • READ
  • WRITE

However, to enable SKIP LOCKED in your query you can use these alternatives:

  • Use specific JPA implementation feature, such as Hibernate LockMode which allows to specify the SKIP LOCKED via a JPA query, thanks to a combination of PESSIMISTIC_WRITE LockModeType Lock Timeout specific setting as described above
  • Create a native SQL query as you did
like image 103
Rémi Bantos Avatar answered Sep 19 '22 13:09

Rémi Bantos