脱离 Spring 实现复杂嵌套事务,之二(REQUIRED - 加入已有事务)
2016-04-07 19:16
483 查看
PROPAGATION_REQUIRED(加入已有事务)
定义:
尝试加入已经存在的事务中,如果没有则开启一个新的事务。解释:
解释 REQUIRED 行为并不困难。它是指如果当前连接中如果已经开启了数据库事务,并且有程序在控制这个事务。那么在处理 REQUIRED 行为时将会忽略 commit/rollback 操作,这是加入已有事务的特征。时间 | 事务1 | 事务2 |
T1 | 开始事务 | |
T2 | 操作1... | |
T3 | 加入事务1 | |
T4 | 操作2... | |
T5 | 操作3... | |
T6 | 递交事务 |
所谓“没有”指的是当前连接中不存在事务(事务状态为false)。“则开启新的事务”这里的可以理解为,如果没有事务那么才开启新的事务。而且新开启的事务是需要事务管理器进行维护的。
工作原理
开启事务
事务管理器在创建 REQUIRED 类型事务时,会取得当前连接这一过程会持有当前连接(引用计数+1)。
然后通过判断当前连接是否存在事务状态,来决定是否通过 doBegin 方法开启事务。这个规则为:如果存在事务状态则忽略,否则开启。
一般情况下在调用 doBegin 方法之前事务都是尚未开启的。我们知道没有开启事务的连接特征是 autoCommit 属性为 true。在这种情况下每一次SQL操作都是独立成为一个事务,因此多条SQL语句之间是不存在事务关系的。换句话说只要进入 doBegin 方法的数据库连接都是没有开启事务的连接,它们都满足 new 状态的特征。
事务中的数据库操作
无论在开启事务的时候Connection 此时此刻,可以直接使用 Connection 接口畅快的使用数据库操作。由于每次进行数据库操作都要反复的申请和释放数据库连接。这会反复的使引用计数 +1,-1。
递交/回滚事务
REQUIRED 行为告诉我们,如果环境中有事务控制,那么该行为下的事务管理器将不作为。所有事务控制操作交给环境中的事务控制来处理。
但是如果环境中不存在事务,那么事务管理器是需要负责 commit & rollback 的。
这时候在前面确定的 new 状态就可以发挥作用了。因为根据 new 状态的特征描述我们知道凡是持有 new 状态的数据库连接在开启事务之前是不存在先前事务的。作为后来者的事务管理器而言,可以放心大胆的去递交事务。
如果不具备 new 特征则正好说明外部在事务管理器之外有其它程序代码代为控制了事务。
例如下面这个业务逻辑(伪代码):
?
上面的代码修改一下如下:
?
而上面第8行,所使用的连接由于也没有开启事务。所以它会以自动递交事务的方式去运行。
关于 afterClear
afterClear 阶段的作用是将当前连接的状态恢复到 getTransaction 方法之前。并且由于 getTransaction 方法会持有当前连接(引用计数++),因此 afterClear 方法也会释放掉这个连接的持有(引用计数--)。
相关文章推荐
- 脱离 Spring 实现复杂嵌套事务,之一(必要的概念)
- java this关键字的使用
- SSM三大框架整合详细教程(Spring+SpringMVC+MyBatis)(转)
- Spring中配置和读取多个Properties文件--转
- Java参数传递,传递引用,传递值浅析
- Neither the JAVA_HOME nor the JRE_HOME environment variable is defined
- JavaEE和JSP有什么区别
- Java用SAX解析XML
- Java核心技术卷1
- Java之绘制五环图案
- 第四,五周——Java编写的电梯模拟系统(结对作业)
- java对日期Date类进行加减运算,年份加减,月份加减
- spring 和 springmvc 的父子容器关系浅析
- java搭建rest服务
- jdk的安装
- jdk的安装
- java 中的 collections.sort() 方法对list的排序
- jdk1.5 静态导入
- spring-mvc.xml参考
- java实现SHA1签名加密