Операция DB откат Grails на некоторых ошибок - PullRequest
1 голос
/ 12 апреля 2011


У меня есть сервис, где можно сохранить много данных в БД. Использование MYSQL Я использовал, как это

Domain1.withTransaction {text->
            def domain1=//Create my domain object to save 
             if(!domain1.save()){
               domain1.errors.each {
                      println it
               }
               throw new RuntimeException('unable to save domain1')
        }
        Domain2.withTransaction {text->
            def domain2=//Create my domain object to save 
             if(!domain2.save()){
               domain2.errors.each {
                      println it
               }
               throw new RuntimeException('unable to save domain2')
        }

Моя проблема, если возникла какая-либо проблема при сохранении домена2, мне также нужно откатить сохранение домена1.
Мне нужно удалить domain1 из БД.

Ответы [ 4 ]

3 голосов
/ 12 апреля 2011

Вместо использования программной обработки транзакций, артефакт Сервиса позволяет автоматически обрабатывать транзакции. Это обычно приводит к более чистому и более понятному коду.

Вы также можете использовать failOnError: true при сохранении (), чтобы вызвать исключение RuntimeException.

Пример ниже:

class SomeService {

    static transactional = false

    def serviceMethod() {
        def domain1=//Create my domain object to save
        def domain2=//Create my domain object to save
        domain1.save(failOnError:true)
        domain2.save(failOnError:true)
    }
}

UPDATE

Я возвращаюсь к этой теме после прочтения ответа на другую тему. Тест интеграции Grails не откатывается

Пожалуйста, убедитесь, что ваш диалект настроен как InnoDB, поскольку таблицы MyISAM не являются транзакционными. Это настроено в вашем Config.groovy

dataSource {
      dialect= org.hibernate.dialect.MySQLInnoDBDialect
      ...
}
1 голос
/ 12 апреля 2011

Попробуйте удалить часть Domain2.withTransaction {text->.Вы уже находитесь в транзакции с вашим первым звонком.Если вы продолжите работать внутри скобок, вы должны остаться в рамках той же транзакции, а domain1 должен быть откатан, если вы выбросите исключение после проверки domain2.

0 голосов
/ 12 апреля 2011

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

Domain1.withTransaction {text->
  def domain1=//Create my domain object to save 
  if (!domain1.save()) {
    domain1.errors.each {
      println it
    }
    throw new RuntimeException('unable to save domain1')
  }

  def domain2=//Create my domain object to save 
    if (!domain2.save()) {
      domain2.errors.each {
        println it
      }
    throw new RuntimeException('unable to save domain2')
  }
}
0 голосов
/ 12 апреля 2011

Поместите это Domain2.withTransaction замыкание в Domain1.withTransaction замыкание, поэтому ошибка в транзакции Domain2 приведет к откату как транзакции Domain1, так и транзакции Domain2
Как это

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