编程式事务管理

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. CSUFT 1002 Robot Navigation

    1002: Robot Navigation Time Limit: 1 Sec      Memory Limit: 128 MB Submit: 4      Solved: 2 Descript ...

  2. client/offset/srooll位置与关系

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  3. Mysql-学习笔记(==》集合函数与分组四)

    -- 聚集函数 配合分组语句 group by-- 显示最高分SELECT MAX(sscore) FROM db.`student`;-- 显示最高分学生的信息min maxSELECT * FRO ...

  4. 2016年11月26日 星期六 --出埃及记 Exodus 20:17

    2016年11月26日 星期六 --出埃及记 Exodus 20:17 "You shall not covet your neighbor's house. You shall not c ...

  5. JAVAWeb使用POI做导出Excel

    一.需要了解的API ①HSSFWorkBook //代表一个Excel文件 ②HSSFSheet //代表一个表 ③HSSFRow //代表一个表中的某一行 ④HSSFCell //代表一个表中的某 ...

  6. 思考之一——PM(Project Manager)

    摘自:http://blog.csdn.net/moreevan/article/details/6697806

  7. 区分一下dpkg,rpm和yum以及apt-get

    一般来说著名的 Linux 系统基本上分两大类: RedHat 系列:Redhat.Centos.Fedora 等 Debian 系列:Debian.Ubuntu 等 Dpkg (Debian系):U ...

  8. 循环,range,continue 和 break

    1.for循环 用户按照顺序循环可迭代对象中的内容, PS:break.continue li = [11,22,33,44] for item in li:     print item 2.enu ...

  9. Python存取XML方法简介

    <?xml version="1.0" encoding="utf-8"?> <Schools> <School Name=&qu ...

  10. include_path详细解析

    include_path详细解析     原文地址:http://www.laruence.com/2010/05/04/1450.html 1.php默认的包含路径为 .;C:\php\pear 即 ...