Question

LockModeType.OPTIMISTIC does not work while LockModeType.OPTIMISTIC_FORCE_INCREMENT does.

@Transactional
public void test(Integer task){

  if (task == 1) {
    em.find(Company.class, 1000059, LockModeType.OPTIMISTIC_FORCE_INCREMENT);
  }

  if (task == 2) {
    em.find(Company.class, 1000059, LockModeType.OPTIMISTIC);
    System.out.println("waiting for task 1 ...");
    Thread.sleep(10000); // time to call task1
  }

}

I am calling task1 inside of task2 and I expect the transaction of task2 to be rolled back but in the end both of them are committed fine. This should not be happen because task2 has optimistic lock on the version of the Company and task1 increments it in the middle. SQLs that had been logged shows that the version is checked in the end of transaction but there is no rollback (JpaOptimisticLockingFailureException).

Task2:

select ... from company where company.id=1000059

Task1:

select ... from company where company.id=1000059
update Company set version=57 where id=1000059 and version=56
commit

Task2:

select version from Company where id =1000059
commit

If I changed OPTIMISTIC to OPTIMISTIC_FORCE_INCREMENT the code would work fine and the outside transaction would be rolled back and JpaOptimisticLockingFailureException would be thrown. But this means that a readonly transaction needs to update the version, what I do not want to :(

I am using Hibernate 4.3.0.Final and Spring 4.0.0.RELEASE

Was it helpful?

Solution

Solved by changing transaction isolation from REPEATABLE-READ to READ COMMITTED on the database level by using

SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED

which can also be done in persistence.xml by adding line:

<property name="hibernate.connection.isolation">2</property>

Where isolation parameter can be:

1: READ UNCOMMITTED
2: READ COMMITTED
4: REPEATABLE READ
8: SERIALIZABLE
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top