Grails 回滚编程性事务
本文总结了编程性事务和声明性事务回滚的两种方法,并提到了一个非常容易忽视的问题。
回滚编程性事务
编程性事务在Grails中是通过withTransaction方法实现的,它接收一个闭包,并且会把TransactionStatus传给这个闭包。要想回滚事务,调用TransactionStatus上的setRollbackOnly()方法即可。下面是一个账户转账的例子:
01 | Account.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或其子类即可。看下面这个例子:
1 | class 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,对比前后数据库中的结果。在做这个实验时,请确保底层的数据库引擎是支持事务的,以免结果不正确。
相关推荐
momode 2020-09-11
思君夜未眠 2020-09-04
行吟阁 2020-08-09
表格的现在还是较为常用的一种标签,但不是用来布局,常见处理、显示表格式数据。在HTML网页中,要想创建表格,就需要使用表格相关的标签。<table> <tr> <td>单元格内的文字</td> ...
gufudhn 2020-08-09
世樹 2020-11-11
SCNUHB 2020-11-10
bleach00 2020-11-10
FellowYourHeart 2020-10-05
jessieHJ 2020-08-19
末点 2020-08-03
nimeijian 2020-07-30
好记忆也需烂 2020-07-28
zlsdmx 2020-07-05
tomson 2020-07-05
tianqi 2020-07-05
onlykg 2020-07-04