Артем,
Не могли бы вы вкратце объяснить, чего вы пытаетесь достичь? Вид с высоты птичьего полета, очевидно - как этот (вызванный из) код пользовательского интерфейса? Или это процесс на стороне сервера (чтобы у вас был прямой контроль над потоками)? Причина, по которой я спрашиваю, состоит в том, что я (возможно, неправильно) чувствую этот и другие связанные с вами вопросы о том, что вы пытаетесь использовать оптимистическую блокировку для чего-то, для чего она не предназначена, и именно это и вызывает все проблемы.
Что касается StaleObjectStateException
, то он определенно генерируется из DefaultFlushEventListener
и AutoFlushEventListener
, которые обрабатывают явные / неявные сбросы. Вы вызываете flush () вручную? Если нет, возможно, исключение перехватывается / регистрируется кодом обертки при автоматической очистке (Spring? TransactionManager? EntityManager?)
Обновление
Спасибо за разъяснение вопроса. Мне все еще немного неясно, хотите ли вы запретить нескольким потокам из одновременно изменять 1 одной и той же сущности или запретить нескольким пользователям от попытки одновременно отредактировать его.
Прежний сценарий может быть обработан через оптимистическую блокировку; однако без явного flush()
он становится недетерминированным (поток, который первым сделал изменение, может не быть сброшен / зафиксирован первым). Смотрите мой ответ на этот вопрос для более подробной информации. Другая проблема с автоматическим сбросом - это то, что вы испытываете в настоящее время - сбой проверки версии не обнаруживается до сброса, и, если этот сброс совпадает с попыткой совершить транзакцию, генерируется исключение RollbackException. В любом случае вся транзакция откатывается.
Последний сценарий (запрещающий пользователям редактирование) НЕ может быть обработан оптимистической блокировкой. Вместо этого вам нужно будет реализовать пессимистическую блокировку - либо на уровне базы данных, либо на уровне приложения. Другими словами, процесс выглядит так:
- пользователь хочет отредактировать сущность
- проверить, существует ли блокировка на сущности
- ДА - запретить редактирование (разрешить просмотр только для чтения?)
- NO - заблокировать объект, разрешить редактирование
- зафиксировать (отменить) изменения; разблокировать замок
Не забудьте истечь существующие блокировки после определенного периода бездействия пользователя, если вы используете этот подход.
одновременное изменение 1 в данном случае не совсем точно (для этого нужны транзакции); мы говорим о том, чтобы запретить одному потоку перезаписывать изменения другого на основе более старой версии.