Использование и контроль транзакций Spring в действиях Struts 2 - PullRequest
5 голосов
/ 21 декабря 2010

Эй, ребята, я некоторое время работал над проектом со следующими компонентами:

  • Struts2.1.8.1,
  • Spring 3.0.3
  • JPA 2.0,
  • Hibernate 3

Я использую магию Spring EntityManager ... Но у меня возникают проблемы с транзакциями внутри моих действий.Например, я устанавливаю значения для моего сохраненного объекта в нескольких методах в своем классе, и я хочу иметь возможность rollback, если метод validate обнаружит ошибку проверки, или commit в противном случае эти изменения.Я уже потратил довольно много времени на чтение половины интернета для всестороннего объяснения.К сожалению, полных примеров не существует (по крайней мере, похоже на мой стек).

Я наткнулся на эту ветку в списке рассылки: @ Аннотация Transactional Spring в действии Struts2 не работает .Похоже, что сообщение, на которое я ссылаюсь, имеет довольно простое и понятное решение: использование TransactionInterceptor поможет, как кажется ... Проблема в том, что я не могу найти полезную информацию об этом перехватчике.

Кто-нибудь, кто имеет здесь опыт работы с этой технологией, может порекомендовать один или два совета о том, как использовать транзакции Spring в действиях Struts2?

Спасибо!

- Изменить 1 -

Я настроил тестовый проект, если вам интересно, просто скачайте файл и попробуйте его (или проверьте его).Спасибо!

Ответы [ 3 ]

4 голосов
/ 21 декабря 2010

Как правило, контроллеры / действия / поддерживающие компоненты / и т. Д. Не обрабатывают транзакции. Действия являются веб-частью вашего внутреннего кода - они должны касаться только сбора данных запроса и отправки данных ответа. Сама логика (включая доступ к базе данных) должна выполняться на другом уровне. Например. сервисный уровень. Таким образом, вы создаете еще один компонент, вводите его в действие и заставляете его работать - userService.register(user). Тогда настройка транзакций на сервисном уровне должна быть тривиальной, поскольку это и в весенней документации, и в бесчисленных примерах:

<tx:annotation-driven /> и @Transactional (кстати, убедитесь, что у вас есть <tx:..> сейчас, это может быть причиной проблемы. Даже если это работает, это не отменяет мое предложение об уровне обслуживания)

1 голос
/ 29 марта 2011

Я не люблю отвечать на свой вопрос, но поскольку я решил это давным-давно ... Я подумал, что должен поделиться знаниями (или отсутствием ... в этом случае).

Книга, которую я использовал для изучения Struts 2 и Spring-JPA-Hibernate, добавляет аннотацию @Transactional прямо перед объявлением класса обслуживания.Это ужасно неправильно, поскольку все методы (в том числе те, которые только извлекают данные из базы данных) находятся внутри транзакции с фиксацией.Короче говоря, все получалось совершенным событием, если возникали исключения.

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

Спасибо Стивену и Кватерниону за то, что они взяливремя ответить на мой вопрос.

0 голосов
/ 21 декабря 2010

Исходя из вашего вопроса, вот что я понимаю о вашей проблеме.

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

Решение

Создать перехватчик, который будет:

  • Начать транзакцию
  • Вызвать действие внутри блока try / catch
  • Откат транзакции, если есть исключение или если в действии есть какие-либо ошибки проверки (это можно обнаружить с помощью action.hasErrors)
  • Совершить транзакцию

Возможно, вы захотите, чтобы этот перехватчик был определен довольно рано в стеке. Я не знаю каких-либо предварительно созданных перехватчиков для этого (хотя они могут быть и некоторые), но его должно быть довольно легко собрать.

Update

Я не использую Spring, поэтому не могу сказать, как там работает поддержка транзакций JPA, но вы можете обрабатывать транзакции для вашего EntityManager, например:

try {
    entityManager.getTransaction().begin();
    // do your thing
    entityManager.getTransaction().commit();
} catch (Exception e) {
    entityManager.getTransaction().rollback();
    throw new PersistenceException(e);
}

Это просто грубый пример, но он должен проиллюстрировать это.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...