grails回滚db操作有些错误

时间:2011-04-12 10:01:04

标签: mysql grails transactions


我有一个服务,在那里将大量数据保存到db。 使用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')
        }

我的问题是如果在保存domain2时出现任何问题我还需要回滚domain1保存 我需要从db中删除domain1。

4 个答案:

答案 0 :(得分:3)

服务工件不允许使用程序化事务处理,而是允许自动事务处理。这通常会使代码更清晰,更易于维护。

当save()强制抛出RuntimeException时,也可以使用failOnError:true。

以下示例:

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)
    }
}

<强>更新

在我阅读了另一个主题的回复之后,我正在重新审视这个主题。 Grails Integration Test Does NOT Rollback

请验证您的方言是否设置为InnoDB,因为MyISAM表不是事务性的。这是在Config.groovy

中配置的
dataSource {
      dialect= org.hibernate.dialect.MySQLInnoDBDialect
      ...
}

答案 1 :(得分:1)

尝试删除Domain2.withTransaction {text-&gt;部分。 您第一次通话时已进入交易。 如果你在括号内做进一步的工作,你应该保持在同一个事务中,如果你在检查domain2之后抛出异常,应该回滚domain1。

答案 2 :(得分:0)

Domain2.withTransaction闭包放在Domain1.withTransaction闭包内,因此Domain2事务中的错误将回滚Domain1和Domain2事务
喜欢这个

Domain1.withTransaction {
      //....
      Domain2.withTransaction {
           //....
      } 
} 

答案 3 :(得分:0)

如果您只想要在抛出未处理的未经检查的异常时回滚单个事务,则不要启动嵌套事务。必要的代码更改如下所示:

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')
  }
}