I'm using Spring data JPA and I have a method that is annotated with Spring's @Transactional annotation. In that method, I fetch entities from DB. Some entities are used for read-only purposes, while some are updated in that transaction. Let's take an example
@Transactional
public void method1(Long id) {
var entityA = repositoryA.findById(id);
var entityB = repositoryB.findByOtherId(id);
entityA.setProperty1(entityB.getProperty() + 1);
}
@Transactional
public void method2(Long id) {
var entityA = repositoryA.findById(id);
var entityB = repositoryB.findByOtherId(id);
entityA.setProperty2(entityB.getProperty() + 2);
}
In the above example let's say entityA
and entityB
correspond to tableA
and tableB
respectively and property1
and property2
are two of the columns of tableA
.
Also, I'm using SQL Server so the default isolation level is READ_COMMITTED
.
I have the following questions:
After executing line
var entityA = repositoryA.findById(id);
how is it determined which type of lock should be acquired? In the above example, we are updating data intableA
and reading data intableB
, so are different locks acquired here?Let's say both
method1
andmethod2
are invoked concurrently with the sameid
. Will the thread that acquired lock first, block the second thread or will both execute in parallel? I understand that the isolation level isREAD_COMMITTED
but the DB doesn't know whether I've made any changes to rows fetched by first thread.If I want to execute both methods in parallel for the same
id
what isolation level should be set? Also in both the methods I'm updating different columns of the same row, so when both the transactions commit will it be the same result as executing those transactions serially? On a side note, when Hibernate flushes the changes during commit phase, for update statements it updates all the fields of the entity, so will there be a lost update in this case?If I were to specify
readOnly=true
in the Transactional annotation, will it have any effect on acquiring of locks?