读书人

Grails 回滚编程性事宜

发布时间: 2012-09-09 09:27:54 作者: rapoo

Grails 回滚编程性事务

本文总结了编程性事务和声明性事务回滚的两种方法,并提到了一个非常容易忽视的问题。

回滚编程性事务

编程性事务在Grails中是通过withTransaction方法实现的,它接收一个闭包,并且会把TransactionStatus传给这个闭包。要想回滚事务,调用TransactionStatus上的setRollbackOnly()方法即可。下面是一个账户转账的例子:

01Account.withTransaction { status -> 02????03????if(source.active) { 04????????source.balance -= amount 05????????if(dest.active) { 06????????????dest.amount += amount 07????????}else { 08????????????status.setRollbackOnly() 09????????} 10????}??? 11}回滚声明性事务

利用服务,可以在Grails中轻松地实现声明性事务。如果要回滚事务,只要在服务的方法中抛出RuntimeException或其子类即可。看下面这个例子:

1class DomainbService { 2????boolean transactional = true 3??????4????def service2() { 5????????new B().save() 6????????throw new RuntimeException("save b failed!") 7????} 8}

这里需要注意的是,在Grails文档中并没有明确指出要抛出的必须是RuntimeException,而只是提到只要抛出Exception就可以了。但实际上,这是错误的。Spring的文档已经指出,对于声明性事务,方法需要抛出一个“unchecked”异常,这样才会触发回滚事务。

不信的话,各位可以试一试,把上面的RuntimeException换成Exception,对比前后数据库中的结果。在做这个实验时,请确保底层的数据库引擎是支持事务的,以免结果不正确。

读书人网 >编程

热点推荐