spring事务配置的学习总结
2011-05-02 23:48
465 查看
之前写的一个系统在测试环境运行了两周都基本正常,但部署到线上运行了几天以后开始持续报唯一键重复的错误。那段代码很简单,就是先检查B表数据是否存在,如果不存在则往A表插数据,再往B表插数据。显然错误就是A表的数据已经插入了,但是B表的数据居然没插入。
代码逻辑肯定没有问题,这个现象显然就是整个这个方法的原子性被破坏了,曾经有一次插入了A表,结果B表没插入,但是A表插入的结果没回滚。经过几处数据核对都与这个猜测是一致的。仔细检查了一下事务配置,并找到一些相关资料学习了下,果然事务配的有严重问题。赶紧把学到的东西记录下来,加深一下理解。
Spring的事务类型一共有7个方式,分别是:
PROPAGATION_REQUIRED -- 支持当前事务,如果当前没有事务,就新建一个事务。这是最常见的选择。
PROPAGATION_SUPPORTS -- 支持当前事务,如果当前没有事务,就以非事务方式执行。
PROPAGATION_MANDATORY -- 支持当前事务,如果当前没有事务,就抛出异常。
PROPAGATION_REQUIRES_NEW -- 新建事务,如果当前存在事务,把当前事务挂起。
PROPAGATION_NOT_SUPPORTED -- 以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
PROPAGATION_NEVER -- 以非事务方式执行,如果当前存在事务,则抛出异常。
PROPAGATION_NESTED -- 如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则进行与PROPAGATION_REQUIRED类似的操作。
其中,REQUIRED是默认的方式,当使用tx标签的时候,写成propagation="REQUIRED"即可。
网上对于这些方式的区别都有说明,我自己写了一些测试代码去确认了一下我的理解,在嵌套中区别明显。用一个简单的场景,方法A去调用方法B,这里我举几个例子:
1. A、B都是REQUIRED,其实两个方法就是合在一个事务里面。那么不论A或B执行的失败,则A、B都会产生回滚。
2. A是REQUIRED,B是REQUIRES_NEW。B方法在进入的时候有自己的savepoint,退出的时候有自己的commit, 那么B方法就是一个独立的事务。如果方法B执行且成功或失败,都与方法A无关。
(注意:这里要显示的去catch B方法的exception,否则异常上抛会造成A方法也失败了)
3. A是REQUIRED,B是NESTED。B方法进入的时候也有自己的savepoint,但是提交的时候是与A方法结束时一起提交,那么B方法执行失败就影响到自己的事务。B执行失败,A依然可以提交。但是A执行失败,B会被回滚。
(注意:同样要catch B方法的exception)
非事务就不举例子了,很好理解。知道上面这几种组合,基本就可以应对大部分情况了。但知道事务配置,还需要理解事务的隔离级别,否则读出来数据与预期有出入也会造成问题。当然大部分情况下默认配置就可以满足需求。
事务隔离级别有以下4种:
1、Serializable:最严格的级别,事务串行执行,资源消耗最大;
2、REPEATABLE READ:保证了一个事务不会修改已经由另一个事务读取但未提交(回滚)的数据。避免了“脏读取”和“不可重复读取”的情况,但是带来了更多的性能损失。
3、READ COMMITTED:大多数主流数据库的默认事务等级,保证了一个事务不会读到另一个并行事务已修改但未提交的数据,避免了“脏读取”。该级别适用于大多数系统。
4、Read Uncommitted:保证了读取过程中不会读取到非法数据。
参考资料:
1. Spring声明式事务管理及事务嵌套
http://blog.csdn.net/mini_snow/archive/2009/08/03/4404654.aspx
2. 对Spring事务配置的五种方式的深入研究
http://webservices.ctocio.com.cn/java/321/9055321.shtml
3. spring事务详解
http://yjsun.javaeye.com/blog/148281
4. 浅谈Spring事务隔离级别
http://developer.51cto.com/art/200906/132336.htm
代码逻辑肯定没有问题,这个现象显然就是整个这个方法的原子性被破坏了,曾经有一次插入了A表,结果B表没插入,但是A表插入的结果没回滚。经过几处数据核对都与这个猜测是一致的。仔细检查了一下事务配置,并找到一些相关资料学习了下,果然事务配的有严重问题。赶紧把学到的东西记录下来,加深一下理解。
Spring的事务类型一共有7个方式,分别是:
PROPAGATION_REQUIRED -- 支持当前事务,如果当前没有事务,就新建一个事务。这是最常见的选择。
PROPAGATION_SUPPORTS -- 支持当前事务,如果当前没有事务,就以非事务方式执行。
PROPAGATION_MANDATORY -- 支持当前事务,如果当前没有事务,就抛出异常。
PROPAGATION_REQUIRES_NEW -- 新建事务,如果当前存在事务,把当前事务挂起。
PROPAGATION_NOT_SUPPORTED -- 以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
PROPAGATION_NEVER -- 以非事务方式执行,如果当前存在事务,则抛出异常。
PROPAGATION_NESTED -- 如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则进行与PROPAGATION_REQUIRED类似的操作。
其中,REQUIRED是默认的方式,当使用tx标签的时候,写成propagation="REQUIRED"即可。
网上对于这些方式的区别都有说明,我自己写了一些测试代码去确认了一下我的理解,在嵌套中区别明显。用一个简单的场景,方法A去调用方法B,这里我举几个例子:
1. A、B都是REQUIRED,其实两个方法就是合在一个事务里面。那么不论A或B执行的失败,则A、B都会产生回滚。
2. A是REQUIRED,B是REQUIRES_NEW。B方法在进入的时候有自己的savepoint,退出的时候有自己的commit, 那么B方法就是一个独立的事务。如果方法B执行且成功或失败,都与方法A无关。
(注意:这里要显示的去catch B方法的exception,否则异常上抛会造成A方法也失败了)
3. A是REQUIRED,B是NESTED。B方法进入的时候也有自己的savepoint,但是提交的时候是与A方法结束时一起提交,那么B方法执行失败就影响到自己的事务。B执行失败,A依然可以提交。但是A执行失败,B会被回滚。
(注意:同样要catch B方法的exception)
非事务就不举例子了,很好理解。知道上面这几种组合,基本就可以应对大部分情况了。但知道事务配置,还需要理解事务的隔离级别,否则读出来数据与预期有出入也会造成问题。当然大部分情况下默认配置就可以满足需求。
事务隔离级别有以下4种:
1、Serializable:最严格的级别,事务串行执行,资源消耗最大;
2、REPEATABLE READ:保证了一个事务不会修改已经由另一个事务读取但未提交(回滚)的数据。避免了“脏读取”和“不可重复读取”的情况,但是带来了更多的性能损失。
3、READ COMMITTED:大多数主流数据库的默认事务等级,保证了一个事务不会读到另一个并行事务已修改但未提交的数据,避免了“脏读取”。该级别适用于大多数系统。
4、Read Uncommitted:保证了读取过程中不会读取到非法数据。
参考资料:
1. Spring声明式事务管理及事务嵌套
http://blog.csdn.net/mini_snow/archive/2009/08/03/4404654.aspx
2. 对Spring事务配置的五种方式的深入研究
http://webservices.ctocio.com.cn/java/321/9055321.shtml
3. spring事务详解
http://yjsun.javaeye.com/blog/148281
4. 浅谈Spring事务隔离级别
http://developer.51cto.com/art/200906/132336.htm
相关文章推荐
- spring学习总结(九):AOP 基础及基于注解配置的AOP
- spring学习总结(十):基于 XML 的配置AOP
- spring配置文件application.xml中的事务总结
- Spring学习总结(24)——Spring配置文件加载路径总结
- spring学习笔记(24)——xml方式配置事务
- Spring学习总结(7)——applicationContext.xml 配置文详解
- 《Spring AOP学习总结之三—AOP对于事务的配置》
- 毕业设计(五)---spring学习笔记(3)之-dataSource,sessionFactory,hibernateTemplate,事务 的简单配置。
- SSH与SSM学习之Spring23——Spring事务之注解配置方式管理事务
- 学习spring 事务管理的配置
- Spring学习总结(7)——applicationContext.xml 配置文详解
- 总结了五种Spring事务的配置方式
- spring框架学习(七)spring管理事务方式之xml配置
- Spring视频学习(十)使用XML配置事务
- Spring学习总结(7)——applicationContext.xml 配置文详解
- Spring学习之xml配置Bean总结
- 18.01.24,web学习第四十五天,还有半年,努力吧青年 Spring第三天 aop事务配置+Spring整合jdbc操作
- 工作流Activiti的学习总结(四)Spring和Activiti的整合配置讲解
- spring 事务管理配置总结
- Spring学习总结(3)——Spring配置文件详解