Spring事务管理
来源:互联网 发布:js二维映射 编辑:程序博客网 时间:2024/06/11 14:09
一、简介
spring支持编程式事务管理和声明式事务管理两种方式。
编程式事务管理使用TransactionTemplate或者直接使用底层的PlatformTransactionManager。对于编程式事务管理,spring推荐使用TransactionTemplate。
声明式事务管理建立在AOP之上的。其本质是对方法前后进行拦截,然后在目标方法开始之前创建或者加入一个事务,在执行完目标方法之后根据执行情况提交或者回滚事务。声明式事务最大的优点就是不需要通过编程的方式管理事务,这样就不需要在业务逻辑代码中掺杂事务管理的代码,只需在配置文件中做相关的事务规则声明(或通过基于@Transactional注解的方式),便可以将事务规则应用到业务逻辑中。
显然声明式事务管理要优于编程式事务管理,这正是spring倡导的非侵入式的开发方式。声明式事务管理使业务代码不受污染,一个普通的POJO对象,只要加上注解就可以获得完全的事务支持。和编程式事务相比,声明式事务唯一不足地方是,后者的最细粒度只能作用到方法级别,无法做到像编程式事务那样可以作用到代码块级别。但是即便有这样的需求,也存在很多变通的方法,比如,可以将需要进行事务管理的代码块独立为方法等等。
声明式事务管理也有两种常用的方式,一种是基于tx和aop名字空间的xml配置文件,另一种就是基于@Transactional注解。显然基于注解的方式更简单易用,更清爽。
事务有四个特性:ACID
原子性(Atomicity):事务是一个原子操作,由一系列动作组成。事务的原子性确保动作要么全部完成,要么完全不起作用。
一致性(Consistency):一旦事务完成(不管成功还是失败),系统必须确保它所建模的业务处于一致的状态,而不会是部分完成部分失败。在现实中的数据不应该被破坏。
隔离性(Isolation):可能有许多事务会同时处理相同的数据,因此每个事务都应该与其他事务隔离开来,防止数据损坏。
持久性(Durability):一旦事务完成,无论发生什么系统错误,它的结果都不应该受到影响,这样就能从任何系统崩溃中恢复过来。通常情况下,事务的结果被写到持久化存储器中。
二、事务的7个传播行为
事务的传播行为是指,如果在开始当前事务之前,一个事务上下文已经存在,此时有若干选项可以指定一个事务性方法的执行行为。在TransactionDefinition定义中包括了如下几个表示传播行为的常量:
1、PROPAGATION_REQUIRED:如果当前存在事务,则加入该事务;如果当前没有事务,则创建一个新的事务。这是默认值;
2、PROPAGATION_REQUIRES_NEW:创建一个新的事务,如果当前存在事务,则把当前事务挂起;
3、PROPAGATION_SUPPORTS:如果当前存在事务,则加入该事务;如果当前没有事务,则以非事务的方式继续运行;
4、PROPAGATION_NOT_SUPPORTED:以非事务方式运行,如果当前存在事务,则把当前事务挂起;
5、PROPAGATION_NEVER:以非事务方式运行,如果当前存在事务,则抛出异常;
6、PROPAGATION_MANDATORY:如果当前存在事务,则加入该事务;如果当前没有事务,则抛出异常;
7、PROPAGATION_NESTED:如果当前存在事务,则创建一个事务作为当前事务的嵌套事务来运行;如果当前没有事务,则该取值等价于PROPAGATION_REQUIRED。
详解参考:Spring事务管理
三、事务的5个隔离级别
先了解什么是 脏数据, 脏读, 不可重复读, 幻读?
脏读: 一个事务正在对数据进行更新操作,但是更新还未提交,另一个事务这时也来操作这组数据,并且读取了前一个事务还未提交的数据,而前一个事务如果操作失败进行了回滚,后一个事务读取的就是错误数据,这样就造成了脏读。
不可重复读: 一个事务多次读取同一数据,在该事务还未结束时,另一个事务也对该数据进行了操作,而且在第一个事务两次次读取之间,第二个事务对数据进行了更新,那么第一个事务前后两次读取到的数据是不同的,这样就造成了不可重复读。
幻觉读: 幻读与不可重复读类似。它发生在一个事务读取了几行数据,接着另一个并发事务插入了一些数据时。在随后的查询中,第一个事务就会发现多了一些原本不存在的记录。
事务的隔离级别有以下5种:
1、default
默认的事务隔离级别
2、read_uncommitted
读未提交,一个事务可以操作另外一个未提交的事务,不能避免脏读,不可重复读,幻读,隔离级别最低,并发性 能最高
3、read_committed
读已提交,一个事务不可以操作另外一个未提交的事务, 能防止脏读,不能避免不可重复读,幻读。
4、repeatable_read
能够避免脏读,不可重复读,不能避免幻读
5、serializable
隔离级别最高,消耗资源最低,代价最高,能够防止脏读, 不可重复读,幻读。
四、代码案例
/** * 1.添加事务注解 * 使用propagation 指定事务的传播行为,即当前的事务方法被另外一个事务方法调用时如何使用事务。 * 默认取值为REQUIRED,即使用调用方法的事务 * REQUIRES_NEW:使用自己的事务,调用的事务方法的事务被挂起。 * * 2.使用isolation 指定事务的隔离级别,最常用的取值为READ_COMMITTED * 3.默认情况下 Spring 的声明式事务对所有的运行时异常进行回滚,也可以通过对应的属性进行设置。通常情况下,默认值即可。 * 4.使用readOnly 指定事务是否为只读。 表示这个事务只读取数据但不更新数据,这样可以帮助数据库引擎优化事务。若真的是一个只读取数据库值得方法,应设置readOnly=true * 5.使用timeOut 指定强制回滚之前事务可以占用的时间。 */ @Transactional(propagation=Propagation.REQUIRES_NEW, isolation=Isolation.READ_COMMITTED, noRollbackFor={UserAccountException.class}, readOnly=true, timeout=3) @Override public void purchase(String username, String isbn) { //1.获取书的单价 int price = bookShopDao.findBookPriceByIsbn(isbn); //2.更新书的库存 bookShopDao.updateBookStock(isbn); //3.更新用户余额 bookShopDao.updateUserAccount(username, price); }
参考:原文
- 事务管理之Spring事务管理
- Spring事务管理
- spring事务管理
- Spring事务管理
- Spring事务管理
- Spring事务管理
- Spring事务管理
- Spring事务管理
- Spring 事务管理
- Spring事务管理
- spring 事务管理
- spring 事务管理
- spring 事务管理
- spring事务管理
- Spring 事务管理
- Spring事务管理
- spring事务管理
- spring 事务管理
- 初学算法——阶乘
- Mybatis 主键返回
- C语言常用基础位操作
- 2017杭电多校联赛 1011 KazaQ's Socks HDU 6043
- 机器学习之求最近邻点
- Spring事务管理
- 分支结构与循环语句
- convention
- 说说VNode节点(Vue.js实现)
- React专利许可证研究
- 深入理解Java虚拟机到底是什么
- 05-继承
- Android从系统调用相册OkHttp上传到服务器(activity数据传递)
- php单引号和双引号的区别