2015-08-14 3 views
1

В чем разница между этими действиями два регулятора:Grails транзакционных услуг вызывает внутри транзакционной действия контроллера

@Transactional 
    def save(SomeDomain someDomain) { 
     someDomain.someProperty = firstService.createAndSaveSomething(params) //transactional 
     someDomain.anotherProperty = secondService.createAndSaveSomething(params) //transactional 
     someDomain.save(flush: true) 
    } 

и

def save(SomeDomain someDomain) { 
     combinedService.createAndSave(someDomain, params) //transactional, encapsulating first and second service calls 
    } 

Моя цель состоит в том, чтобы откатить все сохранить() действие, если сделка не удается , Но не уверен, какой из них я использую.

+0

Можете ли вы показать нам аннотации @Transaction двух сервисов? – saw303

+0

Предполагая, что все мои службы имеют аннотацию @Transactional на уровне класса. – renz

+0

https://github.com/vahidhedayati/test-transactions – Vahid

ответ

3

Вы можете использовать оба подхода.

Ваше объявление № 1 откат транзакции контроллера, когда firstService или secondService исключает.

В листинге # 2 (я ожидаю, что createAndSave метод combinedService быть аннотированный с @Transactional) будет откатить транзакцию, если createAndSave бросает исключение. Большой плюс, использующий этот подход, заключается в том, что этот метод обслуживания теоретически можно использовать повторно в других контроллерах.

0

Одним из ключевых моментов, о @Transactional том, что есть два отдельных понятия, чтобы рассмотреть, каждый с его собственной области и жизненный цикл:

  1. живучесть транзакции контекст
  2. база данных

Само по себе транзакционная аннотация определяет область действия одной транзакции базы данных. Транзакция базы данных происходит внутри области контекста персистентности. Код:

@Transactional 
    def save(SomeDomain someDomain) { 
     someDomain.someProperty = firstService.createAndSaveSomething(params) //transactional 
     someDomain.anotherProperty = secondService.createAndSaveSomething(params) //transactional 
     someDomain.save(flush: true) 
    } 

Контекст настойчивость в JPA EntityManager, реализуемый внутри, используя Hibernate Session (при использовании Hibernate в качестве поставщика сохраняемости). Код:

def save(SomeDomain someDomain) { 
     combinedService.createAndSave(someDomain, params) //transactional, encapsulating first and second service calls 
    } 

Примечание: Контекст живучести просто объект синхронизатора, который отслеживает состояние ограниченного набора объектов Java и убеждается, что изменения на тех объектах, которые в конечном счете сохраняется обратно в базу данных.

Вывод: Механизм управления декларативными транзакциями (@Transactional) является очень мощным, но его можно неправильно использовать или неправильно настроить.

Понимание того, как это работает внутри, полезно при устранении неполадок, когда механизм совсем не работает или работает неожиданным образом.

+0

Не уверен, что вы указываете на их различия. Извините, не могли бы вы уточнить? – renz

+0

Оба сохраняют сеанс спящего режима по-своему, но если вы хотите контролировать реакцию сеанса hibernate, вы можете использовать аннотацию @Transactional, иначе использовать hibernate с сохранением hibernate по умолчанию будет автоматически управлять им. – Abhishek