grails rollback db operation on some error
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')
}
My problem if there occurred any problem in saving domain2 i need to roll back domain1 save also.
I need to remove domain1 from db.Instead of using programatic transaction handling, the Service artifact allows for automatic transaction handling. This typically leads to cleaner and more maintainable code.
You can also use the failOnError:true when you save() to force a RuntimeException to be thrown.
Example below:
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
I'm revisiting this topic, after I read a response to another topic. Grails Integration Test Does NOT Rollback
Please verify that your dialect is setup as InnoDB as MyISAM tables aren't transactional. This is configured in your Config.groovy
dataSource {
dialect= org.hibernate.dialect.MySQLInnoDBDialect
...
}
Try removing the Domain2.withTransaction {text-> part. You are already inside a transaction with your first call. If you do further work inside the brackets, you should stay within the same transaction and domain1 should be rolled back if you throw and exception after checking domain2.
Put that Domain2.withTransaction
closure inside Domain1.withTransaction
closure, so error in Domain2 transaction will rollback both Domain1 and Domain2 transaction
Like this
Domain1.withTransaction {
//....
Domain2.withTransaction {
//....
}
}
If you just want a single transaction which is rolled back when an unhandled unchecked exception is thrown, then don't start a nested transaction. The necessaary code changes are shown below:
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')
}
}
精彩评论