在此之前,我们已经了解了 Spring 相关的基础知识,今天将为给位带来,有关 Spring 事务代理的相关知识。关注我的公众号「Java面典」,每天 10:24 和你一起了解更多 Java 相关知识点。

事务管理方式

在 Spring 项目中,我们可以用通过四种方式实现事务管理,分别是 编程式事务管理、基于 TransactionProxyFactoryBean的声明式事务管理、基于 @Transactional 的声明式事务管理 和 基于Aspectj AOP配置事务。其实现方式如下:

编程式事务管理

// JDBC 事务管理
Connection connection = DriverManager.getConnection("connUrl", "username", "password");
//关闭自动提交,此句代码会自动开启事务。默认为true,自动提交。
connection.setAutoCommit(false); String sql1 = "insert into user(name) values (?)";
PreparedStatement preparedStatement1 = connection.prepareStatement(sql1);
preparedStatement1.setString(1,"Java面典");
preparedStatement1.executeUpdate(); String sql2 = "update user set name=? where id=?";
PreparedStatement preparedStatement2 = connection.prepareStatement(sql2);
preparedStatement2.setString(1, "Java面典 new");
preparedStatement2.setInt(2, 10);
preparedStatement2.executeUpdate(); try{
//提交事务
connection.commit();
}catch (SQLException e){
//失败就回滚
connection.rollback();
} finally {
preparedStatement1.close();
preparedStatement2.close();
connection.close();
}

基于 TransactionProxyFactoryBean的声明式事务管理

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd"> <tx:annotation-driven transaction-manager="transactionManager"/>
</beans>

基于 @Transactional 的声明式事务管理

@Service
public class UserServiceImpl implements IUserService { @Transactional(transactionManager = "transactionManager", rollbackFor = Exception.class)
@Override
public void add(User user) {
// todo
}
}

基于Aspectj AOP配置事务

<!-- 事务管理器 -->
<bean id="tracnsactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean> <tx:advice id="txAdvice" transaction-manager="myTracnsactionManager">
<tx:attributes>
<!-- 为连接点指定事务属性 -->
<tx:method name="add*" isolation="DEFAULT" propagation="REQUIRED"/>
<tx:method name="stockChange" isolation="DEFAULT" propagation="REQUIRED" rollback-for="StockException"/>
</tx:attributes>
</tx:advice> <aop:config>
<!-- 切入点配置 -->
<aop:pointcut expression="execution(* *..service.*.*(..))" id="point"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="point"/>
</aop:config>

事务传播机制

Spring 的事务传播分为以下几个机制:

  • REQUIRED:如果有事务则加入事务,如果没有事务,则创建一个新的(默认值);

  • NOT_SUPPORTED:Spring 不为当前方法开启事务,相当于没有事务;

  • REQUIRES_NEW:不管是否存在事务,都创建一个新的事务,原来的方法挂起,新的方法执行完毕后,继续执行老的事务;

  • MANDATORY:必须在一个已有的事务中执行,否则报错;

  • NEVER:必须在一个没有的事务中执行,否则报错;

  • SUPPORTS:如果其他 bean 调用这个方法时,其他 bean 声明了事务,则就用这个事务,如果没有声明事务,那就不用事务;

    SUPPORTS类型的事务传播机制,是否使用事务取决于调用方法是否有事务,如果有则直接用,如果没有则不使用事务。

  • NESTED:如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则执行与 REQUIRED 类似的操作;

注意事项

在 A 方法内,调用 B 方法时,存在以下规则:

  1. REQUIRED

    当两个方法的传播机制都是 REQUIRED 时,如果一旦发生回滚,两个方法都会回滚;
  2. REQUIRES_NEW

    当 A 方法传播机制为 REQUIRES_NEW ,会开启一个新的事务,并单独提交方法,所以 B 方法的回滚并不影响 A 方法事务提交;
  3. NESTED

    当 A 方法为 REQUIRED,B 方法为 NESTED 时,A 方法开启一个嵌套事务;

    当 A 方法回滚时,B 方法也会回滚;反之,如果 B 方法回滚,则并不影响 A 方法的提交。

事务隔离级别

TransactionDefinition 接口中定义了五个表示隔离级别的常量:

  • ISOLATION_DEFAULT:使用后端数据库默认的隔离界别,MySQL默认采用的REPEATABLE_READ 隔离级别,Oracle 默认采用的 READ_COMMITTED 隔离级别;

  • ISOLATION_READ_UNCOMMITTED:最低的隔离级别,允许读取,允许读取尚未提交的的数据变更,可能会导致脏读、幻读或不可重复读;

  • ISOLATION_READ_COMMITTED:允许读取并发事务已经提交的数据,可以阻止脏读,但是幻读或不可重复读仍有可能发生;

  • ISOLATION_REPEATABLE_READ:对同一字段的多次读取结果都是一致的,除非数据是被本身事务自己所修改,可以阻止脏读和不可重复读,但幻读仍有可能发生;

  • ISOLATION_SERIALIZABLE:最高的隔离级别,完全服从 ACID 的隔离级别。所有的事务依次逐个执行,这样事务之间就完全不可能产生干扰,也就说,该级别可以阻止脏读、不可重复读以及幻读。但是这将严重影响程序的性能。通常情况下也不会用到该级别。

Spring 系列推荐

Spring04——Spring MVC 全解析

Spring03——有关于 Spring AOP 的总结

Spring02——Spring 中 Bean 的生命周期及其作用域

Spring01——你应该了解的,有关 IOC 容器的一切

Spring05——Spring 如何实现事务管理的更多相关文章

  1. spring 声明式事务管理

    简单理解事务: 比如你去ATM机取5000块钱,大体有两个步骤:首先输入密码金额,银行卡扣掉5000元钱:然后ATM出5000元钱.这两个步骤必须是要么都执行要么都不执行.如果银行卡扣除了5000块但 ...

  2. Spring声明式事务管理基于@Transactional注解

    概述:我们已知道Spring声明式事务管理有两种常用的方式,一种是基于tx/aop命名空间的xml配置文件,另一种则是基于@Transactional 注解.         第一种方式我已在上文为大 ...

  3. Spring声明式事务管理基于tx/aop命名空间

    目的:通过Spring AOP 实现Spring声明式事务管理; Spring支持编程式事务管理和声明式事务管理两种方式. 而声明式事务管理也有两种常用的方式,一种是基于tx/aop命名空间的xml配 ...

  4. Spring对Hibernate事务管理

    谈Spring事务管理之前我们想一下在我们不用Spring的时候,在Hibernate中我们是怎么进行数据操作的.在Hibernate中 我们每次进行一个操作的的时候我们都是要先开启事务,然后进行数据 ...

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

    编程式事务管理 Spring 的编程式事务管理概述 在 Spring 出现以前,编程式事务管理对基于 POJO 的应用来说是唯一选择.用过 Hibernate 的人都知道,我们需要在代码中显式调用be ...

  6. Spring学习8-Spring事务管理

      http://blog.sina.com.cn/s/blog_7ffb8dd501014e0f.html   Spring学习8-Spring事务管理(注解式声明事务管理) 标签: spring注 ...

  7. Spring中的事务管理

    事务简介: 事务管理是企业级应用程序开发中必不可少的技术,用来确保数据的完整性和一致性 事务就是一系列的动作,它们被当作一个单独的工作单元.这些动作要么全部完成,要么全部不起作用 事务的四个关键属性( ...

  8. Spring对Hibernate事务管理【转】

    在谈Spring事务管理之前我们想一下在我们不用Spring的时候,在Hibernate中我们是怎么进行数据操作的.在Hibernate中我们每次进行一个操作的的时候我们都是要先开启事务,然后进行数据 ...

  9. Spring中的事务管理详解

    在这里主要介绍Spring对事务管理的一些理论知识,实战方面参考上一篇博文: http://www.cnblogs.com/longshiyVip/p/5061547.html 1. 事务简介: 事务 ...

随机推荐

  1. Hexo之旅(四):文章编写技巧

    hexo 编写文章可以使用以下命令创建hexo new "文件名" #创建的文章会在_pots目录下文章的后缀名是以md命名的文件格式,遵循markdown语法,所以编写文章可以使 ...

  2. 微软发布MS MARCO数据集,提高计算机阅读理解能力

    ​ MARCO数据集,提高计算机阅读理解能力" title="微软发布MS MARCO数据集,提高计算机阅读理解能力"> ​ 本文译自:Microsoft data ...

  3. 先搞清楚这些问题,简历上再写你熟悉Java!

    原创声明 本文作者:黄小斜 转载请务必在文章开头注明出处和作者. 系列文章介绍 本文是<五分钟学Java>系列文章的一篇 本系列文章主要围绕Java程序员必须掌握的核心技能,结合我个人三年 ...

  4. centos7下安装python3.7.2详细教程

    1)下载安装python3.7.2 1:yum -y install zlib-devel bzip2-devel openssl-devel ncurses-devel sqlite-devel r ...

  5. optparse(命令行参数解析工具)

    在用Python做自动化的时候,命令行的解析一定是少不了的,有很多命令行解析工具库,其中Python内建的一个库optparse,还是比较好用的 1.贴代码并注释 # coding=UTF-8 fro ...

  6. Requests功能整理

    import requests # GET r = requests.get('https://api.github.com/events') # POSTr = requests.post('htt ...

  7. win10安装LoadRunner时,安装.net framwork组件报0x800F081F错误 解决办法

    一.报错原因 0x800F081F错误大多数是在安装软件时,系统无法联网自动下载安装. 经过各种排查及搜索解决方案,总结原因无非以下三种: 1.windows update被禁用. 2.电脑没有.ne ...

  8. Javascript学习笔记-基本概念-函数

    ECMAScript 中的函数使用function 关键字来声明,后跟一组参数以及函数体.函数的基本语法如下所示: function functionName(arg0, arg1,...,argN) ...

  9. 跟我猜Spring-Boot:bean的创建

    废话在前 最近几年的技术路子很杂,先是node,然后是php,后来是openresty,再后来转到了java,而接触的框架(Framework),也越发的复杂,从最开始的express/koa,到lu ...

  10. 全差分运算放大器ADA4930的分析(1)

    AD转换芯片的模拟信号输入端方式为:全差分.伪差分.单端输入,其中全差分输入的效果最佳,现阶段ADC转换器为了提高其性能,建议用户使用全差分的输入方式.(AD7982.ADS8317等都能实现信号的全 ...