编程式事务管理

Spring 的编程式事务管理概述

在 Spring 出现以前,编程式事务管理对基于 POJO 的应用来说是唯一选择。用过 Hibernate 的人都知道,我们需要在代码中显式调用beginTransaction()、commit()、rollback()等事务管理相关的方法,这就是编程式事务管理。通过 Spring 提供的事务管理 API,我们可以在代码中灵活控制事务的执行。在底层,Spring 仍然将事务操作委托给底层的持久化框架来执行。

 

转自:http://www.ibm.com/developerworks/cn/education/opensource/os-cn-spring-trans/section4.html

基于底层 API 的编程式事务管理

根据PlatformTransactionManager、TransactionDefinition 和 TransactionStatus 三个核心接口,我们完全可以通过编程的方式来进行事务管理。示例代码如清单4所示:

清单4. 基于底层 API 的事务管理示例代码

public class BankServiceImpl implements BankService {
private BankDao bankDao;
private TransactionDefinition txDefinition;
private PlatformTransactionManager txManager;
......
public boolean transfer(Long fromId, Long toId, double amount) {
TransactionStatus txStatus = txManager.getTransaction(txDefinition);
boolean result = false;
try {
result = bankDao.transfer(fromId, toId, amount);//执行了转账sql
txManager.commit(txStatus); //提交事务
} catch (Exception e) {
result = false;
txManager.rollback(txStatus);//遇到异常,回滚
System.out.println("Transfer Error!");
}
return result;
}
}

相应的配置文件如清单5所示:

清单5. 基于底层API的事务管理示例配置文件

<bean id="bankService" class="footmark.spring.core.tx.programmatic.origin.BankServiceImpl">
<property name="bankDao" ref="bankDao"/>
<property name="txManager" ref="transactionManager"/>
<property name="txDefinition">
<bean class="org.springframework.transaction.support.DefaultTransactionDefinition">
<property name="propagationBehaviorName" value="PROPAGATION_REQUIRED"/>
</bean>
</property>
</bean>

如上所示,我们在类中增加了两个属性:一个是 TransactionDefinition 类型的属性,它用于定义一个事务;另一个是 PlatformTransactionManager 类型的属性,用于执行事务管理操作。

如果方法需要实施事务管理,我们首先需要在方法开始执行前启动一个事务,调用PlatformTransactionManager.getTransaction(...) 方法便可启动一个事务。创建并启动了事务之后,便可以开始编写业务逻辑代码,然后在适当的地方执行事务的提交或者回滚。

 

基于 TransactionTemplate 的编程式事务管理

通过前面的示例可以发现,这种事务管理方式很容易理解,但令人头疼的是,事务管理的代码散落在业务逻辑代码中,破坏了原有代码的条理性,并且每一个业务方法都包含了类似的启动事务、提交/回滚事务的样板代码。幸好,Spring 也意识到了这些,并提供了简化的方法,这就是 Spring 在数据访问层非常常见的模板回调模式。如清单6所示:

清单6. 基于 TransactionTemplate 的事务管理示例代码

public class BankServiceImpl implements BankService {
private BankDao bankDao;
private TransactionTemplate transactionTemplate;
......
public boolean transfer(final Long fromId, final Long toId, final double amount) {
return (Boolean) transactionTemplate.execute(new TransactionCallback(){
public Object doInTransaction(TransactionStatus status) {
Object result;
try {
result = bankDao.transfer(fromId, toId, amount);
} catch (Exception e) {
status.setRollbackOnly();
result = false;
System.out.println("Transfer Error!");
}
return result;
}
});
}
}

相应的XML配置如下:

清单 7. 基于 TransactionTemplate 的事务管理示例配置文件

<bean id="bankService"
class="footmark.spring.core.tx.programmatic.template.BankServiceImpl">
<property name="bankDao" ref="bankDao"/>
<property name="transactionTemplate" ref="transactionTemplate"/>
</bean>

TransactionTemplate 的 execute() 方法有一个 TransactionCallback 类型的参数,该接口中定义了一个 doInTransaction() 方法,通常我们以匿名内部类的方式实现 TransactionCallback 接口,并在其 doInTransaction() 方法中书写业务逻辑代码。这里可以使用默认的事务提交和回滚规则,这样在业务代码中就不需要显式调用任何事务管理的 API。doInTransaction() 方法有一个TransactionStatus 类型的参数,我们可以在方法的任何位置调用该参数的 setRollbackOnly() 方法将事务标识为回滚的,以执行事务回滚。

根据默认规则,如果在执行回调方法的过程中抛出了未检查异常,或者显式调用了TransacationStatus.setRollbackOnly() 方法,则回滚事务;如果事务执行完成或者抛出了 checked 类型的异常,则提交事务。

TransactionCallback 接口有一个子接口 TransactionCallbackWithoutResult,该接口中定义了一个 doInTransactionWithoutResult() 方法,TransactionCallbackWithoutResult 接口主要用于事务过程中不需要返回值的情况。当然,对于不需要返回值的情况,我们仍然可以使用 TransactionCallback 接口,并在方法中返回任意值即可。

spring 编程式事务管理和声明式事务管理的更多相关文章

  1. Spring编程式事务管理和声明式事务管理

    本来想写一篇随笔记一下呢,结果发现一篇文章写的很好了,已经没有再重复写的必要了. https://www.ibm.com/developerworks/cn/education/opensource/ ...

  2. spring入门3-jdbcTemplate简单使用和声明式事务

    1.JdbcTemplate简单使用 1.1.引入相关依赖包 <dependency> <groupId>mysql</groupId> <artifactI ...

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

    事务管理对于企业应用来说是至关重要的,当出现异常情况时,它也可以保证数据的一致性. Spring事务管理的两种方式 spring支持编程式事务管理和声明式事务管理两种方式. 编程式事务使用Transa ...

  4. 事务之三:编程式事务、声明式事务(XML配置事务、注解实现事务)

    Spring2.0框架的事务处理有两大类: JdbcTemplate操作采用的是JDBC默认的AutoCommit模式,也就是说我们还无法保证数据操作的原子性(要么全部生效,要么全部无效),如: Jd ...

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

    本教程将深入讲解 Spring 简单而强大的事务管理功能,包括编程式事务和声明式事务.通过对本教程的学习,您将能够理解 Spring 事务管理的本质,并灵活运用之. 先决条件 本教程假定您已经掌握了 ...

  6. Spring编程式事务管理及声明式事务管理

    本文将深入讲解 Spring 简单而强大的事务管理功能,包括编程式事务和声明式事务.通过对本教程的学习,您将能够理解 Spring 事务管理的本质,并灵活运用之. Spring 事务属性分析 事务管理 ...

  7. 【Spring】编程式事务和声明式事务

    一.概述 二.准备工作 1. 创建表 2. 创建项目并引入Maven依赖 3. 编写实体类 4. 编写Dao层 5. 业务层 6. XML中的配置 7. 测试 三.编程式事务 1. 在业务层代码上使用 ...

  8. Spring编程式事务管理

    --------------------siwuxie095                                 Spring 编程式事务管理         以转账为例         ...

  9. Spring学习之Spring中AOP方式切入声明式事务

    mybatis-spring官方文档说明 一个使用 MyBatis-Spring 的其中一个主要原因是它允许 MyBatis 参与到 Spring 的事务管理中.而不是给 MyBatis 创建一个新的 ...

随机推荐

  1. 最长递增子序列LIS再谈

    DP模型: d(i) 以第 i 个元素结尾的最长递增子序列的长度. 那么就有 d(i) = max(d(j)) + 1;(j<i&&a[j]<a[i]),答案 max(d( ...

  2. java中|与||,&与&&到底有什么区别呢?

    &是位运算符.&&是布尔逻辑运算符.在运行上,&两边的条件都要判断(不管前面的是ture还是false),而&&先判断前面的,若为false,则后面的不 ...

  3. 2016年11月12日 星期六 --出埃及记 Exodus 20:3

    2016年11月12日 星期六 --出埃及记 Exodus 20:3 "You shall have no other gods before me.除了我以外,你不可有别的 神.

  4. Win32工程中使用MFCdll的解决方法

    我的项目是Win32,先使用了 Standard Windows Libraries,可后期又要要使用MFC的dll,所以要更改工程属性 ,MFC 的dll可以使用了,但标准的windows的dll出 ...

  5. Python3基础 while配合random输出10个随机整数

    镇场诗:---大梦谁觉,水月中建博客.百千磨难,才知世事无常.---今持佛语,技术无量愿学.愿尽所学,铸一良心博客.------------------------------------------ ...

  6. linux内核中的GPIO系统之(1):软件框架

    一.前言 作为一个工作多年的系统工程师,免不了做两件事情:培训新员工和给新员工分配任务.对于那些刚刚从学校出来的学生,一般在开始的时候总是分配一些非常简单的任务,例如GPIO driver.LED d ...

  7. 【转载】简述Linux的启动过程

    原文:简述Linux的启动过程 本文将简单介绍一下Linux的启动过程,希望对那些安装Linux的过程中遇到了问题的朋友有些帮助 声明:本人没用过UEFI模式和GPT分区格式,所有关于这两部分的内容都 ...

  8. Hearthstone-Deck-Tracker项目的编译

    https://github.com/HearthSim/Hearthstone-Deck-Tracker https://github.com/HearthSim/HearthDb https:// ...

  9. [HDOJ5791]Two(DP)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5791 题意:给两个数列,求有多少个公共子序列. dp(i,j)表示a1~ai和b1~bj的公共子序列个 ...

  10. [Effective Java]第三章 对所有对象都通用的方法

    声明:原创作品,转载时请注明文章来自SAP师太技术博客( 博/客/园www.cnblogs.com):www.cnblogs.com/jiangzhengjun,并以超链接形式标明文章原始出处,否则将 ...