Reputation: 451
i was wondering if it is possible to rollback multiple changes.
For example
Suppose inside the controller i have three domain saves successively.
domain1.save(flush:true)
domain2.save(flush:true)
domain3.save(flush:true)
now i want the behavior to be such that if any of these three saves fail then the successful saves should also be rolled back i.e i want all these three saves to constitute a single transaction. i was wondering if there is a way to do this in grails? i found withTransaction but that seems to be associated to a particular domain. thanks! for help.
Upvotes: 1
Views: 1114
Reputation: 531
Burt, thank you for this explanation. It helps. MVC becomes MVCS. But please, one more clarification: I understood once, that a controller will want to save an updated class (after binding new params) _on_his_own_ even without my call to .save(). How would this interfere with the already handled/saved class inside a service called in between? Or the controller creates only an Integer from a String and passes the corrected params further to the service, to do there all the stuff, the controller did earlier in the MVC world?
Edit and late reaction: Sorry to not have enough reputations for a comment
Upvotes: 0
Reputation: 75681
withTransaction
has nothing to do with the domain class it's called on, but it's a bit of a hack, because it lets you do silly things like transactional persistence in controllers. Controllers should focus on HTTP-related stuff, and delegate real work to services, which are conveniently transactional by default unless you disable it for a particular service.
Move all database updates and business logic to services, and keep your controllers lightweight and focused on extracting request parameters and doing data binding (e.g. turning the string "12453" into the int 12453 via int foo = params.int('foo')
, and using that data to call service methods, and then passing their return values to the view to be rendered. Controllers should just be routers.
If you want, you can use the @Transactional
annotations to customize how transactions work for a whole service or per-method, but by default a service is transactional even without any annotations. You can do as much work as you like in a method and it will all succeed or all be rolled back. I even do single updates/deletes/inserts in transactional methods to make it simple to later on make things more complicated as needed without having to think about transactions. If all database changes are always transactional, things will in general run a lot better.
Upvotes: 2