Как управлять транзакциями с JAX-RS, Spring и JPA - PullRequest
6 голосов
/ 07 марта 2012

Я использую JAX-RS для предоставления HTTP-интерфейса для управления моделью данных. Модель данных хранится в базе данных и взаимодействует с ней через JPA.

Это позволяет мне модифицировать интерфейс к модели данных в соответствии с требованиями клиентов REST и в большинстве случаев кажется, что он работает достаточно хорошо. Однако я не уверен, как справиться со сценарием, в котором метод, предоставленный ресурсом JAX-RS, требует транзакции, которая влияет на шаблон получения, обновления JPA, commit-on-tx-end, поскольку существует только перенос транзакции. операция get, поэтому обновление никогда не фиксируется. Я вижу, как возникает та же проблема, если для одной операции REST требуется несколько операций JPA.

Поскольку я использую поддержку транзакций Spring, очевидным является применение @Transactional к этим методам в ресурсах JAX-RS. Однако для того, чтобы это работало, Spring должен управлять жизненным циклом ресурсов JAX-RS, и примеры использования, о которых я знаю, имеют ресурсы, создаваемые через «new», когда это необходимо, что в любом случае меня немного нервирует.

Я могу придумать следующие решения:

  1. обновить мои методы JPA, чтобы обеспечить управляемую транзакцией версию всего, что я хочу сделать, из моего интерфейса REST атомарно. Должно работать, хранит транзакции вне уровня JAX-RS, но предотвращает шаблон get, update, commit-on-tx-end и означает, что мне нужно создать очень детализированный интерфейс JPA.
  2. Inject Resource объекты; но они, как правило, хранят состояние, по крайней мере, с идентификатором объекта, с которым взаимодействует
  3. Распределите иерархию ресурсов и внедрите большие суперресурсы без состояния в корне, которые управляют всей иерархией из этого корня; несвязные, большие услуги
  4. Иерархия внедренных, поддерживающих транзакции вспомогательных объектов, не поддерживающих состояние, которые скрывают реальные ресурсы; ресурсы создаются и содержат это состояние, но делегируют вызовы методов вспомогательным объектам

Кто-нибудь получил какие-либо предложения? Вполне возможно, что я где-то упустил какой-то ключевой момент.


Обновление - чтобы обойти отсутствие транзакции в потоке get, update, commit-on-tx-close, я могу открыть метод слияния (объект) EntityManager и вызвать его вручную. Не аккуратный и не решает большую проблему, хотя.


Обновление 2 @skaffman Пример кода: В JPA сервисном слое внедренные аннотации работают

public class MyEntityJPAService {
...
@Transactional(readOnly=true) // do in transaction
public MyEntity getMyEntity(final String id) {
    return em.find(MyEntity.class, id);
}

В ресурсе JAX-RS, созданном новыми, транзакции отсутствуют

public class MyEntityResource {
...
private MyEntityJPAService jpa;
...
@Transactional // not injected so not effective
public void updateMyEntity(final String id, final MyEntityRepresentation rep) {
    MyEntity entity = jpa.getMyEntity(id);
    MyEntity.setSomeField(rep.getSomeField());
    // no transaction commit, change not saved...
}

1 Ответ

4 голосов
/ 07 марта 2012

У меня есть несколько предложений

  1. Введите слой между слоями JPA и JAX-RS. Этот слой будет состоять из управляемых Spring @Transactional bean-компонентов и будет составлять различные операции бизнес-уровня из их компонентных вызовов JPA. Это немного похоже на ваш (1), но сохраняет слой JPA простым.

  2. Замените JAX-RS на Spring-MVC, который предоставляет те же (или аналогичные) функции, включая @PathVariable, @ResponseBody и т. Д.

  3. Программно оберните ваши объекты JAX-RS в транзакционные прокси, используя TransactionProxyFactorybean. Это позволит отменить ваши @Transactional аннотации и сгенерировать прокси, который их соблюдает.

  4. Используйте @Configurable и AspectJ LTW, чтобы Spring мог соблюдать @Transactional, даже если вы создаете объект с помощью `new. См. 8.8.1 Использование AspectJ для добавления объектов домена в зависимости от Spring

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