Spring Data: How to lock a row in a transaction and make other transactions wait until it is released?

Issue

I have a @Transactional method where I request a record using findById() from a Spring Data repository.

Now I want to lock this object in a way that other @Transactional methods if executed in parallel will wait until the lock is released.

What I tried: I went through the documentation of @Lock and LockModeType but I still can’t figure out if it covers my case.

Another option would be select for update on a DB level, but I am not sure it is the best option.

Q: How to lock an Entity object (db row) in a spring data transaction and make other transactions wait?

Solution

What you want is called Pessimistic locking. Spring Data through JPA specification supports that. There are two modes of pessimistic locking available:

I think you are mixing up Transaction isolation with Locking. Through @Transactional annotation you can specify isolation which is applied to the connection, while through spirng-data @Locking you can define the locking mode. The Lock mode is not related to the transaction isolation specified on @Transactional. Effectively if the isolation is SERIALIZEABLE you would not need locking via JPA or spring-data, because the database will take care of it. The locks will be DB controlled in this case.

When you define locking the control is in your hands. Here is a description of the pessimistic lock types.

PESSIMISTIC_WRITE – all transactions including the read only ones will be blocked until the transaction holding the lock is complete. Dirty reads are not allowed.

PESSIMISTIC_READ – when you have this mode , concurrent transactions can read the data of the locked row. All updates need to obtain PESSIMISTIC_WRITE lock.

On top of this you can specify a timeout for the locking transaction completion.

Answered By – Alexander Petrov

This Answer collected from stackoverflow, is licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply

(*) Required, Your email will not be published