Spring事务执行流程
2021-07-31 21:32:37 19 举报
Spring事务执行流程
作者其他创作
大纲/内容
该步骤无意义,单纯的为了少画几根线
TransactionSynchronizationManager.unbindResource解除线程数据源绑定的连接对象
默认值有这两种异常回滚,具体看@Transaction注解rollbackFor的注释
返回执行结果
当前需要挂起的transaction是否为空
TransactionSynchronizationManager#resources
MANDATORY
isExistingTransaction当前是否存在事务
是
NESTED
status.createAndHoldSavepoint()给当前事务保存点属性设置值SAVEPOINT_1
事务挂起流程将线程绑定的属性都清空(连接、连接绑定等),并将原来的属性全部封装到一个SuspendedResourcesHolder对象中
关闭连接的自动提交、标记激活事务
1.获取拦截器执行链 ExposeInvocationIntecepter、TransactionIntecpter2. 获取当前方法的TransactionAttribute、TransactionManager强转为PlatformTransactionManager、得到joinpointIdentification(方法全名称)3.根据TransactionAttribute从PlatformTransactionManager得到TransactionStatus,该步骤会创建事务 1.创建一个数据源事务对象(DataSourceTransactionObject),根据数据源获从TransactionSynchronizationManager#resources(ThreadLocal)取一个连接(ConnectionHolder),第一次连接会是空。设置事务源对象的连接和是否新事务的属性并返回。 2.判断当前是否存在事务,第一次进来不会存在,走下面流程,判断当前传播属性,如果要事务挂起,会做具体的挂起操作。第一次也不需要挂起 3.开始事务,判断是否需要同步,创建一个新的事务DefaultTransactionStatus对象 4.真正的开启事务,获取一个连接对象,包装成ConnectionHolder 设置到事务对象中、设置隔离级别、是否只读、关闭自动提交、标记激活事务、绑定连接到线程中。3.将连接和是否新事务设置给据源对象(DataSourceTransactionObject),最后返回事务对象,3.根据上面四个对象创建TransactionInfo、将得到的TransactionInfo绑定到当前线程的TransactionAspectSupport#transactionInfoHolder(ThreadLocal)4. 执行被增强的方法BookService#checkout,调用bookDao.updateStock方法5.执行第2步一样的流程6.根据TransactionAttribute从PlatformTransactionManager得到TransactionStatus 1.创建一个数据源事务对象(DataSourceTransactionObject),根据数据源获从TransactionSynchronizationManager#resources(ThreadLocal)取一个连接(ConnectionHolder)拿到上面创建的连接对象。事务源对象的连接和是否新事务的属性并返回。 2.走存在事务的分支,判断传播属性,并处理NOT_SUPPORTED、REQUIRES_NEW都会挂起当前事务。Nested 3.创建一个新事务,走3.3的流程 4.走3.4一样的流程7. 执行被增强的方法BookDao#updateStock8. 异常根据TransactionInfo回滚,正常走清理当前事务信息和将老的事务信息绑定到线程,根据TransactionInfo进行事务提交9.提交过程根据TransactionInfo中的TransactionStatus 1.根据TransactionStatus判断是否是一个全新的事务、是否有全局回滚标识。调用连接的commit进行提交10回到BookService#checkout,异常根据TransactionInfo回滚,正常走清理当前事务信息和将老的事务信息绑定到线程,根据TransactionInfo进行事务提交11.走9的流程
提交后清除线程私有同步状态triggerAfterCompletion
AbstractPlatformTransactionManager#suspend(transaction)事务挂起流程
txInfo.getTransactionManager().commit根据txInfo.getTransactionStatus进行commit
localRollbackOnly | |globalRollbackOnly true ?
AbstractPlatformTransactionManager#processCommit处理事务的提交
否
是否存在有ConnectionHolder
status.releaseHeldSavepoint()清除保存点
conHolder.getConnection().rollback((Savepoint) savepoint)调用数据库驱动回滚到保存点(只回滚保存点后的代码)
设置事务对象的为同步事务、隔离级别、只读属性
obtainDataSource().getConnection()根据数据源获取连接对象
resourcesHolder.suspendedResources获取挂起事务信息
是否有保存点?
txObject.getConnectionHolder().getConnection获取数据库连接对象Connection
rollbackToSavepoint回滚保存点
status.getSuspendedResources是否有挂起事务
// 新创建事务 private final Object transaction;// 是否需要新事物 private final boolean newTransaction; // 是否需要新同步 private final boolean newSynchronization; // 是否只读 private final boolean readOnly; // 是否要debug private final boolean debug; // 是否有挂起的连接资源 private final Object suspendedResources;
doSuspend(transaction)具体的挂起工作
getConnection().commit()获取Connection对象,调用MySql的comit方法
def.getPropagationBehavior()获取当前方法的传播特效
是,将连接绑定到当前线程
返回值包装成SuspendedResourcesHolder
true
doBegin开启连接和事务
transactionStatus.localRollbackOnly
commitTransactionAfterReturning(txInfo)成功后提交,会进行资源储量,连接释放,恢复挂起事务等操作
设置线程ThreadLocal的actualTransactionActivecurrentTransactionIsolationLevelcurrentTransactionReadOnlycurrentTransactionNamesynchronizations绑定线程资源
CglibAopProxy.DynamicAdvisedInterceptor#interceptCglib AOP增强方法执行的入口
triggerAfterCommit(status)执行事务提交后的回调
当前事务对象是否是一个新的ConnectionHolder
definition.getPropagationBehavior()获取当前方法的传播特效
status.setCompleted设置当前事务状态为完成
当前不存在事务,就会抛异常
synchronizations.remove();\t\tcurrentTransactionName.remove();\t\tcurrentTransactionReadOnly.remove();\t\tcurrentTransactionIsolationLevel.remove();\t\tactualTransactionActive.remove();
getTransaction->doGetTransaction获取TransactionStatus对象
获取TransactionInfo =
suspend(null)没有事务会挂起一个空事务
REQUIRES_NEW
doSetRollbackOnly(status)设置当前事务readOnly为truespan style=\
其它
getConnectionHolderForSavepoint获取ConnectionHolder对象
此处开启的事务会保存之前事务的SuspendedResourcesHolder
获取拦截器执行链ExportInvocationIntercepterTransactionIntercepter
执行增强的方法
startTransaction -->newTransactionStatus开启一个新事务
createTransactionIfNecessary
AbstractTransactionStatus
创建一个空的事务
doResume
cleanupTransactionInfo清除事务信息
TransactionSynchronizationManager.getResource(obtainDataSource())获取数据源,根据数据源获取ConnectionHolder对象
将老的事务信息赋值到线程私有变量TransactionAspectSupport#transactionInfoHolder
txObject.isNewConnectionHolder()是否是一个新事物
是否存在激活事务
直接抛异常,不允许事务存在
TransactionInfo老的事务信息
返回空
TransactionStatus
事务执行前准备工作
这里只会返回suspendedResources,没有存在激活事务那么多属性
REQUIREDREQUIRES_NEWNESTED
doRollback执行回滚操作
status.hasSavepoint()是否有保存点
txObject.setConnectionHolder设置事务对象的ConnectionHolder属性,并标识为一个新的ConnectionHolder
con.rollback()MySql的回滚
TransactionInfo
是否存在
是一个新事务?
setSavepoint(null)设置当前事务的保存点为空
txObject.setConnectionHolder(null)设置事务对象的连接为null
是否是一个新的同步事务
prepareSynchronization新同步事务的设置,针对于当前线程的设置
useSavepointForNestedTransaction嵌套事务的处理
handleExistingTransaction处理已存在的事务
挂起当前食事务后创建一个空事务
cleanupAfterCompletion
NOT_SUPPORTED
status.isNewTransaction()是否是一个新的事务
TransactionSynchronizationManager.clear()线程同步状态清理
doCleanupAfterCompletion
异常
NEVER
finally
是否是一个新的事务?
此方法做清除连接相关操作,比如重置自动提交啊,只读属性啊,解绑数据源啊,释放连接啊,清除链接持有器属性
TransactionStatus连接、挂起事务
//是否需要回滚 private boolean rollbackOnly = false; //事务是否完成 private boolean completed = false;//事务的保存点 给nested用 private Object savepoint;
DefaultTransactionDefinition
DataSourceTransactionManager#doCommit事务开始提交
设置是否允许保存点传播特性NESTED需要用到
TransactionSynchronizationManagercurrentTransactionNamecurrentTransactionReadOnlycurrentTransactionIsolationLevelactualTransactionActive这些ThreadLocal拿到值后全部清空
当前事务是否设置了全局回滚
PlatformTransactionManager数据源
根据事务状态信息,完成后数据清除,和线程的私有资源解绑,重置连接自动提交,隔离级别,是否只读,释放连接,恢复挂起事务等
第一次创建事务,肯定不存在,不存在返回null不处理,后面用到ConnectHolder时再创建
set autocommit=0;start TRANSACTION;DELETE from student where id=1;SAVEPOINT a;DELETE from student where id=2;ROLLBACK TO a;只会删除id= 1的
RuntimeExcepion || Error ?
DefaultTransactionStatus
TransactionSynchronizationManager
AbstractPlatformTransactionManager#processRollback处理事务回滚
设置ConnectionHolder
这里实际上是先创建事务,给事务设置一个嵌套事务的保存点
joinpointIdentification = methodIdentification()获取方法的连接点:标识类名+方法名
new DataSourceTransactionObject()创建数据源事务对象
determineTransactionManagerTransactionManager -->PlatformTransactionManager获取事务管理器对象
resume恢复挂起的事务
收藏
收藏
0 条评论
下一页