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<T>, 翻看该接口的源码:

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 }  
时间: 2024-10-12 23:47:33

Spring事务管理的另一种方式--TransactionTemplate编程式事务管理简单入门的相关文章

Spring事务管理的实现方式:编程式事务与声明式事务

本文转载于本人另一博客[http://blog.csdn.net/liaohaojian/article/details/70139151] 1.上篇文章讲解了Spring事务的传播级别与隔离级别,以及分布式事务的简单配置,点击回看上篇文章 2.编程式事务:编码方式实现事务管理(代码演示为JDBC事务管理) Spring实现编程式事务,依赖于2大类,分别是上篇文章提到的PlatformTransactionManager,与模版类TransactionTemplate(推荐使用).下面分别详细介

Spring的编程式事务和声明式事务

事务管理对于企业应用来说是至关重要的,当出现异常情况时,它也可以保证数据的一致性. Spring事务管理的两种方式 spring支持编程式事务管理和声明式事务管理两种方式. 编程式事务使用TransactionTemplate或者直接使用底层的PlatformTransactionManager.对于编程式事务管理,spring推荐使用TransactionTemplate. 声明式事务是建立在AOP之上的.其本质是对方法前后进行拦截,然后在目标方法开始之前创建或者加入一个事务,在执行完目标方法

Spring学习8-Spring事务管理(编程式事务管理)

一.Spring事务的相关知识   1.事务是指一系列独立的操作,但在概念上具有原子性. 比如转账:A账号-100, B账号+100,完成.这两个操作独立是没问题的. 但在逻辑上,要么全部完成,要么一起失败.    1)jdbc事务:每个Connection都带有一个事务,只是默认被设置为自动提交.一个连接可以有多个事务.对于JDBC,只有在同一个连接内,才有讨论是否提交的前提. 2)Hibernate事务:本质上也是使用JDBC来处理事务.但是不是直接操作,而是使用Session来操作事务.S

全面分析 Spring 的编程式事务管理及声明式事务管理--转

开始之前 关于本教程 本教程将深入讲解 Spring 简单而强大的事务管理功能,包括编程式事务和声明式事务.通过对本教程的学习,您将能够理解 Spring 事务管理的本质,并灵活运用之. 先决条件 本教程假定您已经掌握了 Java 基础知识,并对 Spring 有一定了解.您还需要具备基本的事务管理的知识,比如:事务的定义,隔离级别的概念,等等.本文将直接使用这些概念而不做详细解释.另外,您最好掌握数据库的基础知识,虽然这不是必须. 系统需求 要试验这份教程中的工具和示例,硬件配置需求为:至少带

spring事务管理——编程式事务、声明式事务

本教程将深入讲解 Spring 简单而强大的事务管理功能,包括编程式事务和声明式事务.通过对本教程的学习,您将能够理解 Spring 事务管理的本质,并灵活运用之. 先决条件 本教程假定您已经掌握了 Java 基础知识,并对 Spring 有一定了解.您还需要具备基本的事务管理的知识,比如:事务的定义,隔离级别的概念,等等.本文将直接使用这些概念而不做详细解释.另外,您最好掌握数据库的基础知识,虽然这不是必须. 系统需求 要试验这份教程中的工具和示例,硬件配置需求为:至少带有 512MB 内存(

分析 Spring 的编程式事务管理及声明式事务管理(转)

开始之前 关于本教程 本教程将深入讲解 Spring 简单而强大的事务管理功能,包括编程式事务和声明式事务.通过对本教程的学习,您将能够理解 Spring 事务管理的本质,并灵活运用之. 先决条件 本教程假定您已经掌握了 Java 基础知识,并对 Spring 有一定了解.您还需要具备基本的事务管理的知识,比如:事务的定义,隔离级别的概念,等等.本文将直接使用这些概念而不做详细解释.另外,您最好掌握数据库的基础知识,虽然这不是必须. 系统需求 要试验这份教程中的工具和示例,硬件配置需求为:至少带

Spring 的编程式事务管理及声明式事务管理

本文将深入讲解 Spring 简单而强大的事务管理功能,包括编程式事务和声明式事务.通过对本教程的学习,您将能够理解 Spring 事务管理的本质,并灵活运用之. Spring 事务属性分析 事务管理对于企业应用而言至关重要.它保证了用户的每一次操作都是可靠的,即便出现了异常的访问情况,也不至于破坏后台数据的完整性.就像银行的自助取款机,通常都能正常为客户服务,但是也难免遇到操作过程中机器突然出故障的情况,此时,事务就必须确保出故障前对账户的操作不生效,就像用户刚才完全没有使用过取款机一样,以保

Spring Boot 整合 Shiro ,两种方式全总结!

在 Spring Boot 中做权限管理,一般来说,主流的方案是 Spring Security ,但是,仅仅从技术角度来说,也可以使用 Shiro. 今天松哥就来和大家聊聊 Spring Boot 整合 Shiro 的话题! 一般来说,Spring Security 和 Shiro 的比较如下: Spring Security 是一个重量级的安全管理框架:Shiro 则是一个轻量级的安全管理框架 Spring Security 概念复杂,配置繁琐:Shiro 概念简单.配置简单 Spring

全面分析 Spring 的编程式事务管理及声明式事务管理

转自:http://www.open-open.com/lib/view/open1414310646012.html 关于本教程 本教程将深切讲授 Spring 庞杂而丁壮夜的事务治理功用,包括编程式事务和声明式事务.经由进程对本教程的进修,您将可以理解 Spring 事务治理的实质,并无邪运用之. 先决前提 本教程假定您已掌控了 Java 根蒂根抵常识,并对 Spring 有一定意见.您还需求具有根抵的事务治理的常识,好比:事务的界说,隔离级其他概念,等等.本文将直接行使这些概念而不做具体正