Spring事务管理的另一种方式--TransactionTemplate编程式事务管理简单入门
本文内容纲要: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核心方法:
1 public class TransactionTemplate extends DefaultTransactionDefinition 2 implements TransactionOperations, InitializingBean {
3
4
5 public <T> T execute(TransactionCallback<T> action) throws TransactionException {
6 if (this.transactionManager instanceof CallbackPreferringPlatformTransactionManager) {
7 return ((CallbackPreferringPlatformTransactionManager) this.transactionManager).execute(this, action);
8 }
9 else {
10 TransactionStatus status = this.transactionManager.getTransaction(this);
11 T result;
12 try {
13 result = action.doInTransaction(status);
14 }
15 catch (RuntimeException ex) {
16 // Transactional code threw application exception -> rollback
17 rollbackOnException(status, ex);
18 throw ex;
19 }
20 catch (Error err) {
21 // Transactional code threw error -> rollback
22 rollbackOnException(status, err);
23 throw err;
24 }
25 catch (Exception ex) {
26 // Transactional code threw unexpected exception -> rollback
27 rollbackOnException(status, ex);
28 throw new UndeclaredThrowableException(ex, "TransactionCallback threw undeclared checked exception");
29 }
30 this.transactionManager.commit(status);
31 return result;
32 }
33 }
由上面的代码可以推测到, 真正执行业务方法的关键代码是: action.doInTransaction(status);
正好, 有个入参TransactionCallback
1 public interface TransactionCallback<T> {2
5 T doInTransaction(TransactionStatus status);
6
7 }
该接口只有一个doInTransaction方法, 那么很简单, 我们可以通过匿名内部类的方式将业务代码放在doInTransaction中:
举例如下:
1 private PayOrderDAO payOrderDAO; 2
3 protected TransactionTemplate transactionTemplate;
4
5 /**
6 * 保存支付订单
7 */
8 protected PayOrder savePayReq(final PayOrder payOrder) {
9
10 @Autowired
11 private TransactionTemplate transactionTemplate;
12
13 @Autowired
14 private PayOrderDAO payOrderDAO;
15
16 PayOrder order = (PayOrder) this.transactionTemplate
17 .execute(new TransactionCallback() {
18 @Override
19 public Object doInTransaction(TransactionStatus status) {
20 // 查看是否已经存在支付订单,如果已经存在则返回订单主键
21 PayOrder payOrderTemp = payOrderDAO.findOrder(String
22 .valueOf(payOrder.getPayOrderId()));
23
24 // 由支付渠道类型(PayChannelType)转换得到交易类型(PayType)
25 if (payOrder.getPayChannelId().equalsIgnoreCase(PAY_CHNL_ACT_BAL)) {// 账户余额支付
26 payOrder.setPayType("3");
27 } else if (payOrder.getPayChannelId().equalsIgnoreCase(PAY_CHNL_FAST_PAY)) {// 联通快捷支付
28 payOrder.setPayType("4");
29 } else {// 网银网关支付
30 payOrder.setPayType("2");
31 }
32
33 // 比对新的支付金额与原订单金额是否一致,如不一致则提示错误
34 if (payOrderTemp == null) {
35 String orderId = payOrderDAO.save(payOrder);
36 payOrder.setPayOrderId(orderId);
37 return payOrder;
38 } else {
39 return payOrderTemp;
40 }
41 }
42 });
43 if ("2".equals(order.getOrderState())) {// 2:表示支付成功
44 throw new EpaymentBizException(StatusCode.DQSystem.PAY_FAIL,
45 "同一订单不能重复支付");
46 } else if (payOrder.getPayAmt().longValue() != order.getPayAmt()
47 .longValue()) {
48 throw new EpaymentBizException(StatusCode.DQSystem.PAY_FAIL,
49 "交易金额与原订单不一致");
50 } else {
51 return payOrder;
52 }
53
54 }
本文内容总结:Spring事务管理的另一种方式--TransactionTemplate编程式事务管理简单入门
原文链接:https://www.cnblogs.com/wyisprogramming/p/6944878.html
以上是 Spring事务管理的另一种方式--TransactionTemplate编程式事务管理简单入门 的全部内容, 来源链接: utcz.com/z/362775.html