Это проблема, аналогичная Принудительному откату транзакции при ошибке проверки Сценарий таков: Пользователь редактирует страницу, транзакция устанавливается в MANUAL, поэтому только если мы вызовем flush, она будет зафиксирована в базе данных. Теперь пользователь хочет отменить изменения. Легко, потому что ты еще не смыл его.
Теперь рассмотрим следующий сценарий: пользователь редактирует страницу с большим количеством ajax. Некоторые из этих обратных вызовов ajax требуют запросов к базе данных (например, с использованием окна предложений richFaces и т. д.). Также выполняется некоторая проверка, которая требует поиска в базе данных. Проблема в том, что Hibernate автоматически выдает сброс при выполнении запроса.Таким образом, пользователь не нажимает кнопку сохранения (которая сбрасывает транзакцию), а нажимает кнопку отмены. Чем вы сейчас занимаетесь?
Если вы ничего не сделаете, изменения будут записаны в базу данных, а не то, что ожидает пользователь.
Вы можете создать исключение с аннотацией
@ApplicationException(rollback=true)
, которое приведет к откату транзакции. Затем вы можете перенаправить на другую страницу. Однако здесь я столкнулся с другой проблемой: на некоторых страницах, на которые вы перенаправляете, вы получаете исключение отложенной инициализации. Я указал
#{messages['cancel.rollback']}
в файле pages.xml, поэтому диалог должен завершиться до того, как мы выполним перенаправление. Должен начаться новый разговор (с новой транзакцией), но, похоже, это происходит не во всех случаях? Почему?
Я читал где-то еще, что вы можете просто использовать
Transaction.instance().rollback();
Это было бы предпочтительнее, так как вам не нужно проходить через исключения (перенаправление всегда занимает много времени, когда Seam обрабатывает исключения), но проблема в том, что транзакция не на самом деле не откатился. Я не мог понять, почему. Если я проверяю статус транзакции, он говорит, что она не находится в состоянии отката.
Как лучше всего обрабатывать запросы на отмену? Чистый РУЧНОЙ сброс в этом случае не работает. Вы можете работать с отдельными объектами, но страница содержит несколько связанных объектов, так что это становится беспорядочным.
Обновление: теперь я обнаружил, что создание исключения ApplicationException не откатывает транзакцию во всех случаях. Так что довольно запутался сейчас.
Обновление 2: Конечно, откат транзакций не будет работать, если у вас есть страница, на которой вы используете ajax для обновления значений. Каждая транзакция охватывает только один запрос.Итак, если вы делаете, например. 5 изменений с запросом ajax, откат транзакции приведет только к откату изменений из последнего запроса ajax, а не из предыдущих 4.
Таким образом, решение состоит в том, чтобы использовать РУЧНОЙ режим очистки.
Есть несколько вещей, которые вызовут сброс, даже если вы укажете MANUAL.
Вы можете хотите указать РУЧНОЙ как режим по умолчанию в component.xml