Ручной откат транзакций в Seam

Это проблема, аналогичная Принудительному откату транзакции при ошибке проверки Сценарий таков: Пользователь редактирует страницу, транзакция устанавливается в 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.

  • запрос в ajax-запросе может вызвать сброс — используйте setFlushMode(FlushMode.COMMIT) в запросе, чтобы избежать этого.
  • Сохранение объекта может вызвать сброс в зависимости от используемого поколения ID (например, если вы используете стратегию IDENTITY). Вы можете обойти это, используя Cascades. Если вам нужно создать объекты во время редактирования, которые не имеют реальной связи с основным объектом, который вы редактируете, просто добавьте их в список и сохраните все объекты в этом списке при сохранении.
  • Когда вы начинаете вложенную беседу или к беседе присоединяется другой bean-компонент, режим сброса в этом сеансе снова устанавливается на AUTO, если вы не укажете @Begin(join=true,flushMode=FlushModeType.MANUAL)

Вы можете хотите указать РУЧНОЙ как режим по умолчанию в component.xml


6
задан Community 23 May 2017 в 12:12
поделиться