2011-04-12 37 views
1


我有一個服務,而把大量的數據保存到數據庫。 使用MySQL 我用這樣的Grails的回滾DB操作上的一些錯誤

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。

回答

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

UPDATE

我重新審視這個話題,後來看了一個話題的響應。 Grails Integration Test Does NOT Rollback

請驗證您的方言是否設置爲InnoDB,因爲MyISAM表不是事務性的。這是在你的配置Config.groovy

dataSource { 
     dialect= org.hibernate.dialect.MySQLInnoDBDialect 
     ... 
} 
+0

不適合我。如果'domain2.save'導致RuntimeException,我可以在我的數據庫中看到domain1.save的效果。 – Jithin 2011-04-13 07:04:45

+0

有沒有我需要爲此設置的任何配置? – Jithin 2011-04-13 09:19:16

+0

你能驗證服務/ Grails的-應用程序/服務中?另外,依賴注入是聲明式事務處理的唯一方式。如果您使用新的運營商,如新SomeService() – 2011-04-13 14:08:46

1

嘗試取出Domain2.withTransaction {文本的>一部分。 您已經與您的第一個電話在事務內。 如果你做的括號內的進一步工作,你應該留在同一個事務中,如果你把和檢查DOMAIN2後異常DOMAIN1應該回滾。

0

把那Domain2.withTransaction瓶蓋內Domain1.withTransaction關閉,域2交易這樣的錯誤將回滾兩個域1和域2交易
喜歡這個

Domain1.withTransaction { 
     //.... 
     Domain2.withTransaction { 
      //.... 
     } 
} 
+0

我不認爲MySQL支持嵌套事務。但也許這一切都發生在實際擊中分貝之前? – 2011-04-13 02:18:37

+0

我完全不知道它..無論如何它的工作對我來說。 – 2011-04-13 09:17:56

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