Подтвердить что ты не робот

Откат транзакции в службе Grails

Я обновляю все свои сервисы, чтобы быть транзакционными, используя способность Grail к откату, когда RuntimeException загружается в службу. В большинстве случаев я делаю это:

def domain = new Domain(field: field)
if (!domain.save()) {
   throw new RuntimeException()
}

В любом случае, я хотел проверить, действительно ли это откат транзакции... Мне было интересно, на данный момент он уже совершен. Также, если нет, будет ли настройка flush: true change that? Я не очень хорошо знаком с тем, как Spring/Hibernate делает все это:)

4b9b3361

Ответ 1

Да, это сделает.

Транзакции в Grails по умолчанию обрабатываются на уровне метода сервиса. Если метод возвращается нормально, то транзакция будет совершена, если будет выбрано RuntimeException, транзакция будет отменена.

Обратите внимание, что это означает, что даже если вы используете flush: true при сохранении объекта в методе сервера, изменения db все равно будут отменены, если вы выкинете исключение RuntimeException.

Например:

class MyService {

 def fiddle(id,id2){
   def domain = Domain.findById(id)

   domain.stuff = "A change"
   domain.save( flush:true ) // will cause hibernate to perform the update statements

   def otherDomain = OtherDomain.findById(id2)      

   otherDomain.name = "Fiddled"

   if( !otherDomain.save( flush:true )){ // will also write to the db
     // the transaction will be roled back 
     throw new RuntimeException("Panic what the hell happened")
   }                                                           
 }
}

То, что я не на 100% проясняю с помощью Grails, - это то, что произойдет, если проверенное исключение выбрано в прямом Java/ spring мире, поведение по умолчанию для транзакционного inceptor для совершения транзакции, поскольку это может быть переопределено в config.

Примечание. Существует предостережение, и именно этот ваш db должен поддерживать транзакции в таблицах, которые вы обновляете. Да, это вызывается в MySQL:)

Это также относится к методу Domain.withTransaction.

Ответ 2

Просто хотел добавить дополнительные комментарии к принятому ответу, и это было слишком долго, чтобы вписаться в комментарий.

То, что я не на 100% понимаю с помощью Grails, - это то, что происходит, если выбрано исключенное исключение

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

Если вы действительно хотите проверить исключения для метода, вы можете явно указать метод службы как @Transactional и использовать rollbackFor, чтобы указать, какие исключения должны по-прежнему вызывать откат. (Обратите внимание, что я на самом деле не проверял это.)

Помните, однако, что маркирование любого метода в службе с помощью @Transactional отключает автоматическую упаковку других методов транзакцией. Итак, если вы делаете это ради одного, вы должны сделать это для всех. Убедитесь, что вам действительно нужно объявить те проверенные исключения;)

Подробнее об этом можно узнать на http://docs.grails.org/latest/guide/services.html.