Spring 事务编程

使用TransactionTemplate进行编程式事务管理

org.springframework.transaction.support.TransactionTemplate对与PlatformTransactionManager相关的事务界定操作以及相关的异常处理进行了模板化封装, 开发人员更多的关注于通过相应的callback接口提供具体的事务界定内容即可。spring针对TransactionTemplate提供了两个callback接口,TransactionCallback和TransactionCallbackWithoutResult,二者的唯一区别就是是否需要返回执行结果。
使用TransactionTemplate进行事务管理的代码看起来要比直接使用PlatformTransactionManager要简洁并且容易管理的多:
TransactionTemplate txTemplate = ...;
Object result = txTemplate.execute(new TransactionCallback(){
public Object doInTransaction(TransactionStatus txStatus) {
Object result = null;
// 各种事务操作 ...
return result;
}});
或者
txTemplate.execute(new TransactionCallbackWithoutResult(){
@Override
protected void doInTransactionWithoutResult(TransactionStatus txStatus) {
// 事务操作1
// 事务操作2
// ...
}});
TransactionTemplate会捕捉TransactionCallback或者TransactionCallbackWithoutResult事务操作中抛出的“unchecked exception”并回滚事务,然后将“unchecked exception”抛给上层处理, 所以,现在我们只需要处理特定于应用程序的异常即可,而不用像直接使用PlatformTransactionManager那样对所有可能的异常都进行处理。

如果事务处理期间没有任何问题,TransactionTemplate最终会为我们提交事务,唯一需要我们干预的就只剩下某些情况下的事务回滚了。 如果在TransactionCallback或者TransactionCallbackWithoutResult的事务操作过程中需要让当前事务回滚而不是最终提交,一般来说,我们有两种方式:
抛出“unchecked exception”,TransactionTemplate会为我们处理事务的回滚。 如果事务操作中可能抛出“checked exception”,这种情况下就得在callback内部捕获,然后转译为“unchecked exception”后抛出。
txTemplate.execute(new TransactionCallbackWithoutResult(){
@Override
protected void doInTransactionWithoutResult(TransactionStatus txStatus) {
try
{
...
}
catch(CheckedException e)
{
// throw specific exception here, avoid generic RuntimeException
throw new RuntimeException(e);
}
}});


使用callback接口暴露的TransactionStatus将事务标记为rollBackOnly,TransactionTemplate在最终提交事务的时候如果检测到rollBackOnly标志状态被设置,将把提交事务改为回滚事务:
txTemplate.execute(new TransactionCallbackWithoutResult(){
@Override
protected void doInTransactionWithoutResult(TransactionStatus txStatus) {
boolean needRollback = false;
...
if(needRollback)
txStatus.setRollbackOnly();
}});

对于将事务操作中可能抛出的“checked exception”,如果既想回滚事务又不想让它以“unchecked exception”的形式向上层传播的话, 我们当然不能通过将其转译成“unchecked exception”的方式来处理啦,不过我们现在却可以通过TransactionStatus设置rollBackOnly:
txTemplate.execute(new TransactionCallbackWithoutResult(){
@Override
protected void doInTransactionWithoutResult(TransactionStatus txStatus) {
try
{
...
}
catch(CheckedException e)
{
logger.warn("Tranaction is Rolled back!",e);
txStatus.setRollbackOnly();
}
}});

这种情况下需要注意一个问题,千万不要只“txStatus.setRollbackOnly()”而忘记记录日志,虽然大家可能都知道“swallow exception”是不对的, 但这个地方确实容易忽略日志的记录,从而造成事务回滚了,而我们却不知道的情况。 当发现数据库中本来应该删除的数据却依然存在,并且日志中也没有任何异常信息的时候,你就得挠脑袋很长时间来发现到底哪里出了问题了,程序没跑?才怪!

使用TransactionTemplate虽然要比直接使用PlatformTransactionManager更加便捷,但TransactionTemplate无法处理当事务操作中需要向上层抛出原来的“checked exception”的情况, 你应该也发现了,实际上TransactionCallback或者TransactionCallbackWithoutResult的方法定义中没有声明可以抛出任何“checked exception”,直接使用PlatformTransactionManager则没有这样的限制。 不过,这应该并不会过多的限制TransactionTemplate展现其“个人魅力”吧?!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值