2014-01-30 1 views
2

LockModeType.OPTIMISTIC не работает во время LockModeType.OPTIMISTIC_FORCE_INCREMENT.LockModeType.OPTIMISTIC не работает

@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 
    } 

} 

Я зову TASK1 внутри task2 и я ожидаю, что сделка TASK2 быть откат, но в конце концов оба они совершаются в порядке. Этого не должно быть, потому что Task2 имеет оптимистичную блокировку версии компании, а task1 увеличивает ее посередине. SQL-запросы, которые были зарегистрированы, показывают, что версия проверена в конце транзакции, но откат не выполняется (исключение 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 

Если я изменил оптимистичным OPTIMISTIC_FORCE_INCREMENT код будет работать нормально и внешняя транзакция будет откат и JpaOptimisticLockingFailureException будет выбрано. Но это означает, что для чтения транзакция должна обновить версию, что я не хочу :(

Я использую Hibernate 4.3.0.Final и Spring 4.0.0.RELEASE

ответ

1

решена путем изменения изоляции транзакций от REPEATABLE-READ ЧИТАТЬ COMMITTED на уровне базы данных, используя

SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED 

, который также может быть сделано в persistence.xml путем добавления строки:

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

Где изо может быть:

1: READ UNCOMMITTED 
2: READ COMMITTED 
4: REPEATABLE READ 
8: SERIALIZABLE