Yep that'll do it.
Transactions in Grails are by default handled at a Service method level. If the method returns normally then the transaction will be committed, if a RuntimeException is throw the transaction will be rolled back.
Note this means even if you use flush:true on while saving an object in the server method the db changes will still be rolled back if you throw a RuntimeException.
For example:
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")
}
}
}
What I'm not 100% clear on with Grails is what happens if a checked exception is thrown in straight java/spring world the default behaviour is for the transaction inceptor to commit the transaction, althrough this can be overriden in the config.
Note: there is a caveat, and that is that your db has to support transactions on the tables you are updating. Yes, this is poke at MySQL :)
This also applies to the Domain.withTransaction
method.