61. Spring事务传播行为实现原理
Spring的事务信息是存在ThreadLocal中的, 所以一个线程永远只能有一个事务
- 融入:当传播行为是融入外部事务则拿到ThreadLocal中的Connection、共享一个数据库连接共同提交、回滚;
- 创建新事务:当传播行为是创建新事务,会将嵌套新事务存入ThreadLocal、再将外部事务暂存起来; 当嵌套事务提交、回滚后,会将暂存的事务信息恢复到ThreadLocal中
调用:融入
try{
3.内嵌:判断ThreadLocal是否已经有Connection,有的话就说明是一个内嵌事务, 判断当前事务的传播行为
融入:不会创建Connection,返回事务状态信息(TransactionInfo.newTransaction=false)
1外部.创建一个数据库连接Connection存入ThreadLocal, 并且修改数据库连接的autoCommit属性为false ,返回事务状态信息(TransactioInfo.newTransaction=true)
2外部.然后执行目标方法方法(调用了内部事务方法)方法中会执行数据库操作sql
4.内嵌:然后执行目标方法方法方法中会执行数据库操作sql
}
catch{
如果出现了异常,并且这个异常是需要回滚的就会回滚事务,否则仍然提交事务
}
5内嵌:判断newTransaction==true 就提交事务
6.外部: 判断newTransaction==true 拿到ThreadLocal中的Connection进行提交
调用:创建新事务
try{
3.内嵌:判断ThreadLocal是否已经有Connection,有的话就说明是一个内嵌事务, 判断当前事务的传播行为
创建新事务:会把外层事务相关的事务信息(Connection、隔离级别、是否只读....暂存同时会把外层事务的ThreadLocal存储的事务信息都置空)
创建Connection放入ThreadLocal,返回事务状态信息(TransactionInfo.newTransaction=ture,TransactionInfo.外部事务的信息暂存)
1外部.创建一个数据库连接Connection存入ThreadLocal, 并且修改数据库连接的autoCommit属性为false ,返回事务状态信息(TransactionInfo.newTransaction=true)
2外部.然后执行目标方法方法(调用了内部事务方法)方法中会执行数据库操作sql
4.内嵌:然后执行目标方法方法方法中会执行数据库操作sql
}
catch{
如果出现了异常,并且这个异常是需要回滚的就会回滚事务,否则仍然提交事务
}
5内嵌:判断newTransaction==true 就提交事务, 判断是否暂存事务, 把暂存的事务信息回归ThreadLocal中
6.外部: 判断newTransaction==true 拿到ThreadLocal中的Connection进行提交