Спящий режим - оптимистическая блокировка по умолчанию для отдельных объектов? - PullRequest
1 голос
/ 06 января 2011

У меня есть приложение, которое выполняет:

void deleteObj(id){
    MyObj obj = getObjById(id);
    if (obj == null) {
        throw new CustomException("doesn't exists");
    }
    em.remove(obj);//em is a javax.persistence.EntityManager
}

Я не настроил явно оптимистическую блокировку с полем версии. Однако, если два запроса выполняются параллельно, пытается удалитьтот же объект, тогда я иногда получаю HibernateOptimisticLockingFailureException и иногда «CustomException».

Нормально ли получить HibernateOptimisticLockingFailureException без явной установки оптимистической блокировки?Есть ли в спящем режиме оптимистическая блокировка по умолчанию для отдельных объектов?

Что вы делаете для обработки этого исключения HibernateOptimisticLockingFailureException?Повторить попытку или сообщить пользователю сообщение по умолчанию, например «сервер занят»?

1 Ответ

4 голосов
/ 07 января 2011

Прежде всего, HibernateOptimisticLockingFailureException является результатом механизма преобразования исключений в постоянстве Spring. Это брошено в ответ на StaleStateException, чей Javadoc говорит:

Выдается при сбое проверки номера версии или отметки времени, что указывает на то, что сеанс содержит устаревшие данные (при использовании длинных транзакций с контролем версий). Также происходит, если мы пытаемся удалить или обновить несуществующую строку.

Исходя из здравого смысла, исключение оптимистической блокировки возникает, когда оператор модификации данных возвращает неожиданное количество затронутых строк. Это может быть вызвано несоответствием значения версии, а также отсутствием строки вообще.

Чтобы убедиться, что сущность была фактически удалена, вы можете попытаться сбросить контекст на em.flush() сразу после удаления и отловить выброшенное им исключение (обратите внимание, что это должен быть подкласс PersistenceException с StaleStateException в качестве причины ).

...