1

Я использую Hibernate 2.6 с hibernate-entitymanager. Я пытаюсь поймать и обработать ситуации, когда 2 транзакции конфликтуют с объектом. Вот что происходит:Как обнаружить конфликты транзакций с Hibernate?

Два потока обновляют один объект, у которого есть поле @Version. Поток, который теряет фиксацию журнала гонок StaleObjectStateException на флеш. Исключение не выбрасывается, оно только регистрируется. Я предполагаю, что транзакция отмечена откатом - только в этот момент.

После этого, когда поток пытается выполнить commit, он не работает с RollbackException. Я не нашел способа узнать в коде, почему транзакция откатывается назад.

Есть ли способ поймать и обработать такие ситуации в коде? В основном я хочу поймать StaleObjectStateException, но проблема в том, что она не выбрасывается.

UPDATE: То, что я пытаюсь сделать с высоты птичьего полета выглядит следующим образом:

У меня есть приложение J2EE, работающее под управлением JBoss. Он имеет некоторые внутренние службы, вызванные таймером, и те, которые вызываются из пользовательского интерфейса. Он также имеет одну критическую сущность. Мне нужно убедиться, что разные потоки не могут одновременно обновлять объекты этого класса сущности, поскольку это может привести к несогласованности данных. Вот почему я реализую оптимистичную блокировку.

Когда возникает проблема блокировки с оптимизацией, я стараюсь в целом справиться с этой ситуацией. Я хочу поймать его на очень высоком уровне и показать правильное сообщение пользователя (в моем случае самый высокий уровень - ExceptionMapper для RestEasy). Проблема в том, что когда я поймаю RollbackException, уже слишком поздно.

Не ручаю вручную. Большинство моих EJB используют CMT, и сеансы автоматически очищаются.

+0

Я обновил свой ответ на основе вашего разъяснения – ChssPly76

ответ

0

Посмотрите на NHProf. Это может помочь вам со всеми вещами, связанными с профилированием Nhibernate.

+0

Я использую Hibernate для Java, а не NHibernate. И я не вопрос профилирования, а об исключительных ситуациях обработки – artemb

+0

профилировщик поможет вам обнаружить такие проблемы и сузить их. NHProf - поддерживает также Hibernate. –

2

Артем,

Вы можете кратко объяснить, что это вы пытаетесь достичь? Взгляд на птичий глаз, очевидно - как это (вызвано из) кода пользовательского интерфейса? Или это серверный процесс (так что у вас есть прямой контроль над потоками)? Причина, по которой я спрашиваю, - это получить (возможно, неправильное) чувство от этого и других связанных с ним вопросов, которые вы пытаетесь использовать оптимистичную блокировку для чего-то, для чего она не предназначена, и вот что вызывает все проблемы.

Что касается StaleObjectStateException, он определенно выбрасывается из обоих DefaultFlushEventListener и AutoFlushEventListener, которые обрабатывают явные/неявные флеши. Вы вызываете flush() вручную? Если нет, то, возможно, исключение поимки/регистрироваться код обертки вокруг автоматического смыва (Spring? TransactionManager? EntityManager?)

Update

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

Бывший сценарий можно обрабатывать с помощью оптимистической блокировки; однако без явного flush() он становится недетерминированным (нить, которая сделала модификацию, сначала не может быть сначала сброшена/выполнена). См. Мой ответ на this question для получения более подробной информации. Еще одна проблема с автоматическим сбросом - это то, что вы в настоящее время испытываете. Ошибка проверки версии не обнаружена до сброса, и если этот сброс совпадает с попыткой совершить транзакцию, исключение выбрано RollbackException. В любом случае, полная транзакция отменяется.

Последний сценарий (предотвращающий редактирование пользователей) НЕ МОЖЕТ быть обработан оптимистичной блокировкой. Вместо этого вам потребуется реализовать пессимистическую блокировку - либо на уровне базы данных, либо на уровне приложения. Другими словами, процесс:

  1. пользователь хочет изменить юридическое лицо
  2. проверить, если блокировка существует на сущности
  3. ДА - запретить редактирование (разрешить только чтение смотреть?)
  4. NO - блокировка объекта , разрешить редактирование
  5. фиксация (отмена) изменений; блокировка замка

Обязательно закройте существующие замки после определенного периода бездействия пользователя, если вы идете с этим подходом.


одновременно модифицируя не очень точны в этом случае (это то, что сделки на); мы говорим о том, чтобы один поток не перезаписывал изменения другого, основанного на более старой версии.

+0

Спасибо. Я обновил вопрос с информацией, которую вы задали. – artemb

+0

Я пытаюсь предотвратить одновременное изменение нескольких потоков. Точно не позволяя одному потоку переписывать изменения другого на более раннюю версию. Итак, ваш совет промывается вручную? Только так я смогу достичь своей цели? – artemb

+0

Рассмотрите это: потоки T1 и T2 одновременно читают вашу сущность, изменяют ее, затем T1 сохраняет ее, а T2 сохраняет ее. С автопотоком вы не знаете, чьи изменения (T2 или T1) будут сначала очищены. Кроме того, до тех пор, пока изменения не будут очищены (и/или транзакции, совершенные в зависимости от изоляции), другой поток даже не знает, что версия объекта изменилась, поэтому вы возвращаете ошибку только тогда, когда транзакция завершается с ошибкой и откат. Если вы заботитесь о заказе на изменение или хотите получить исключение на ранней стадии, вы должны выполнить ручную ручную установку. – ChssPly76

Смежные вопросы