Spring事务管理的另一种方式--TransactionTemplate编程式事务管理简单入门
1, 一直以来, 在用Spring进行事物管理时, 只知道用声明式的策略, 即根据不同的数据源, 配置一个事物管理器(TransactionManager), 通过配置切面(PointCut)应用到相应的业务方法上或者直接在方法上加@Ttransactional注解.
这种事务管理使用起来比较简单,但个人感觉灵活性欠缺了点.
2, 最近看公司项目代码, 发现有位同事在他的模块了用了另外一种事务管理方式, 查了一下,TransactionTemplate是编程式事务管理.需要自己手动在每个业务方法中实现事务.
3, TransactionTemplate使用(不一定全面):
A, 在DAO层的配置文件中, 配置TransactionTemplate, 需要注入TransactionManager
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean> <bean id="transactionTemplate"
class="org.springframework.transaction.support.TransactionTemplate">
<property name="transactionManager">
<ref bean="transactionManager"/>
</property>
</bean>
B, 将TransactionTemplate注入到业务层方法中, 并使用:
首先分析一下TransactionTemplate的核心原理:
TransactionTemplate核心方法:
public class TransactionTemplate extends DefaultTransactionDefinition
implements TransactionOperations, InitializingBean { public <T> T execute(TransactionCallback<T> action) throws TransactionException {
if (this.transactionManager instanceof CallbackPreferringPlatformTransactionManager) {
return ((CallbackPreferringPlatformTransactionManager) this.transactionManager).execute(this, action);
}
else {
TransactionStatus status = this.transactionManager.getTransaction(this);
T result;
try {
result = action.doInTransaction(status);
}
catch (RuntimeException ex) {
// Transactional code threw application exception -> rollback
rollbackOnException(status, ex);
throw ex;
}
catch (Error err) {
// Transactional code threw error -> rollback
rollbackOnException(status, err);
throw err;
}
catch (Exception ex) {
// Transactional code threw unexpected exception -> rollback
rollbackOnException(status, ex);
throw new UndeclaredThrowableException(ex, "TransactionCallback threw undeclared checked exception");
}
this.transactionManager.commit(status);
return result;
}
}
由上面的代码可以推测到, 真正执行业务方法的关键代码是: action.doInTransaction(status);
正好, 有个入参TransactionCallback<T>, 翻看该接口的源码:
public interface TransactionCallback<T> {
T doInTransaction(TransactionStatus status);
}
该接口只有一个doInTransaction方法, 那么很简单, 我们可以通过匿名内部类的方式将业务代码放在doInTransaction中:
举例如下:
private PayOrderDAO payOrderDAO; protected TransactionTemplate transactionTemplate; /**
* 保存支付订单
*/
protected PayOrder savePayReq(final PayOrder payOrder) { @Autowired
private TransactionTemplate transactionTemplate; @Autowired
private PayOrderDAO payOrderDAO; PayOrder order = (PayOrder) this.transactionTemplate
.execute(new TransactionCallback() {
@Override
public Object doInTransaction(TransactionStatus status) {
// 查看是否已经存在支付订单,如果已经存在则返回订单主键
PayOrder payOrderTemp = payOrderDAO.findOrder(String
.valueOf(payOrder.getPayOrderId())); // 由支付渠道类型(PayChannelType)转换得到交易类型(PayType)
if (payOrder.getPayChannelId().equalsIgnoreCase(PAY_CHNL_ACT_BAL)) {// 账户余额支付
payOrder.setPayType("3");
} else if (payOrder.getPayChannelId().equalsIgnoreCase(PAY_CHNL_FAST_PAY)) {// 联通快捷支付
payOrder.setPayType("4");
} else {// 网银网关支付
payOrder.setPayType("2");
} // 比对新的支付金额与原订单金额是否一致,如不一致则提示错误
if (payOrderTemp == null) {
String orderId = payOrderDAO.save(payOrder);
payOrder.setPayOrderId(orderId);
return payOrder;
} else {
return payOrderTemp;
}
}
});
if ("2".equals(order.getOrderState())) {// 2:表示支付成功
throw new EpaymentBizException(StatusCode.DQSystem.PAY_FAIL,
"同一订单不能重复支付");
} else if (payOrder.getPayAmt().longValue() != order.getPayAmt()
.longValue()) {
throw new EpaymentBizException(StatusCode.DQSystem.PAY_FAIL,
"交易金额与原订单不一致");
} else {
return payOrder;
} }
Spring事务管理的另一种方式--TransactionTemplate编程式事务管理简单入门的更多相关文章
- Spring事务管理的实现方式:编程式事务与声明式事务
1.上篇文章讲解了Spring事务的传播级别与隔离级别,以及分布式事务的简单配置,点击回看上篇文章 2.编程式事务:编码方式实现事务管理(代码演示为JDBC事务管理) Spring实现编程式事务,依赖 ...
- Spring事务管理的实现方式之编程式事务与声明式事务详解
原创说明:本博文为原创作品,绝非他处转载,转载请联系博主 1.上篇文章讲解了Spring事务的传播级别与隔离级别,以及分布式事务的简单配置,点击回看上篇文章 2.编程式事务:编码方式实现事务管理(代码 ...
- Spring事务管理实现方式之编程式事务与声明式事务详解(转)
原文:https://blog.csdn.net/liaohaojian/article/details/70139151 编程式事务 编码方式实现事务管理(代码演示为JDBC事务管理) Spring ...
- 深入理解TransactionTemplate编程式事务
Spring可以支持编程式事务和声明式事务. Spring提供的最原始的事务管理方式是基于TransactionDefinition.PlatformTransactionManager.Transa ...
- TransactionTemplate编程式事务管理方式的进阶使用---自定义拓展模板类
1, 前面一篇的文章介绍了TransactionTemplate的基本使用方法. 同事在其基础上又做了一层封装,这样更贴合本公司的业务与规范. 2, 首先定义了两个接口: ServiceTemplat ...
- Spring的编程式事务和声明式事务
事务管理对于企业应用来说是至关重要的,当出现异常情况时,它也可以保证数据的一致性. Spring事务管理的两种方式 spring支持编程式事务管理和声明式事务管理两种方式. 编程式事务使用Transa ...
- spring的声明式事务和编程式事务
事务管理对于企业应用来说是至关重要的,当出现异常情况时,它可以保证数据的一致性. Spring事务管理的两种方式 1.编程式事务 使用Transaction Ttempleate或者直接使用底层的Pl ...
- Spring事务:一种编程式事务,三种声明式事务
事务隔离级别 隔离级别是指若干个并发的事务之间的隔离程度.TransactionDefinition 接口中定义了五个表示隔离级别的常量: TransactionDefinition.ISOLATIO ...
- 春天的事务之9.3编程式事务 - 跟我学spring3
9.3编程式事务 9.3.1编程式事务概述 所谓编程式事务指的是通过编码方式实现事务,即类似于JDBC编程实现事务管理. Spring框架提供一致的事务抽象,因此对于JDBC还是JTA事务都是采用相同 ...
随机推荐
- scrapy抓取淘宝女郎
scrapy抓取淘宝女郎 准备工作 首先在淘宝女郎的首页这里查看,当然想要爬取更多的话,当然这里要查看翻页的url,不过这操蛋的地方就是这里的翻页是使用javascript加载的,这个就有点尴尬了,找 ...
- 什么是nginx?
1.nginx是一款服务器软件 2.nginx是一个高性能的HTTP和反向代理服务器: 3.nginx是一个代理邮件服务器: 4.nginx还可以实现负载均衡: nginx的优缺点: 优点:可以实现高 ...
- PHP中单引号和双引号的区别
双引号里面的字段会经过编译器解释,然后再当作HTML代码输出:单引号里面的不进行解释,直接输出: PHP引号使用原则 1.字符串的值用单引号 2.PHP中尽量用单引号,HTML代码全部用双引号 3.在 ...
- Linq用法笔记
一.什么是Linq? LINQ即Language Integrated Query(语言集成查询),LINQ是集成到C#和Visual Basic.NET这些语言中用于提供查询数据能力的一个新特性. ...
- spingMVC aop不生效的解决方式
从网上搜索了一些资料,参考了下面的这个解决方案 http://blog.csdn.net/mmm333zzz/article/details/16858209
- python连接impala(安装impyla)
相关环境如下: Python3.4 Win7 64位 参照官网https://github.com/cloudera/impyla中的安装步骤执行: 1.pip install six 2.pip i ...
- MySQL删除表方式差异
数据库删除语句 Drop/Delete/Truncate比较 Delete :删除数据表中的行(可以删除某一行,也可以在不删除数据表的情况下删除所有行). 删除某一行:Delete from 数据表名 ...
- Chapter 5. MPEG-4 Visual
本章着重介绍有关MPEG-4 Visual标准的细节. Tool 编码工具集合的子集(比如支持交织等). Object 视频元素(比如一个矩形视频帧,或者一个任意形状的区域,静止的图像). Profi ...
- 分享几个 git 的使用场景
你真的会使用 git 吗?你能回答下面几个问题吗? 有三个commit(顺序:CommitA.CommitB.CommitC),它们相互独立,没有依赖. 在不修改B.C的前提下,修改A,怎么操作? 合 ...
- 多表链接 Left join
select * from( select U_User.LinkMan, SP_Approval.* ,SP_Approval_Msg.ApprovalUserID,ROW_NUMBER() ...