Transactional Controller Plugin
Dependency :
compile ":transactional-controller:0.1.1"
Summary
Installation
grails install-plugin transactional-controller
plugins {
runtime 'org.grails.plugins:transactional-controller:0.1'
}Description
It enables executing controller's actions within a transaction, rolling it back,
if an error occurs. The plugin produces the same effect as when the action's code
would be wrapped with a domain class withTransaction method.The source code available at http://github.com/pedjak/grails-transactional-controllerImagine now that an instance of B is not valid for some provided values.
Save rises the exception, but saving of A will not be rolled back.
These are the situations where the plugin is useful.The above statement specifies that the actions of FooController only should be made transactional.
Configuring via the application config is useful when we need to tweak controllers that are part of
some plugins we use.By setting the field's value to 'false', controller's actions will be not executed
within transactions (default Grails behavior anyway).The field can accept as well a list of strings representing names of actions
that should be transactional:Similar to withTransaction method, transactional actions can query
and edit the status of the transaction at runtime by accessing
an additional injected request.txstatus property (an instance of Spring's TransactionStatus)
Why
Many examples demonstrate how to add/update instances of domain classes within a controller's action, but you should understand that this could leave the database in an inconsistent state, if an exception occurs. Consider the following example:class Controller { def update = {
new A(value:params.valueA).save(validate:true, flush:true)
new B(value:params.valueB).save(validate:true, flush:true)
} }How
- assigning a closure to controller.actions.transactional property in Config.groovy.
controller.actions.transactional = { cc ->
cc.name == "Foo" ? true : false
}A statement like controller.actions.transactional = { true } is valid, but not recommended, because it would significantly impact the application performances. In general, only actions that might leave the database in an inconsistent state should be made transactional.
- adding the following static field in the controller and setting
static transactional = true
class SampleController { static transactional = ["add", "update"] def add = { } def update = { } def get = { }
}