Spring 事务实现
Spring 事务使用
@Transactional注解配置项事务传播行为PROPAGATION_REQUIRED当前方法必须在事务中,没有就创建,有就加入。PROPAGATION_SUPPORTS有事务就加入,没有就以非事务方式执行。PROPAGATION_MANDATORY有事务就加入,没有就抛出异常。PROPAGATION_REQUIRES_NEW永远创建新事务执行,之前若有事务则挂起之前的事务。PROPAGATION_NOT_SUPPORTED以非事务方式执行。之前若有事务则挂起之前的事务。PROPAGATION_NEVER以非事务方式执行。之前若有事务则抛出异常。PROPAGATION_NESTED当前若有事务,则在嵌套事务内执行。如果当前没有事务,则按 REQUIRED 属性执行。事务隔离级别readOnly设置超时时间异常回滚设置rollbackForrollbackForClassNamenoRollbackFornoRollbackForClassName
Spring 事务实现
总体流程
启动阶段创建代理对象(参见AOP逻辑)获取切面列表创建aop代理对象
事务执行获取事务属性获取事务管理器,创建事务创建物理连接autoCommit等连接属性设置物理连接和当前线程绑定调用目标方法,执行业务逻辑回滚/提交事务前置处理物理连接执行rollback/commit操作后置处理后置清理清理threadLocal重置autoCommit关闭连接重置 connectionHolder
启动阶段创建代理对象逻辑
参考我之前写的 Spring AOP 实现。
启动阶段创建代理对象逻辑
执行阶段调用链路
事务执行阶段,会通过启动阶段生成的代理类调用目标方法,在此之前通过 TransactionAspectSupport 处理自动开启事务/提交事务等逻辑。调用链路如下:
aop.framework.CglibAopProxy.CglibMethodInvocation#proceed
事务处理流程aop.framework.ReflectiveMethodInvocation#proceedtransaction.interceptor.TransactionInterceptor#invoke事务拦截器处理transaction.interceptor.TransactionAspectSupport#invokeWithinTransaction 事务内调用目标方法transaction.interceptor.TransactionAspectSupport#getTransactionAttributeSourcetransaction.interceptor.AbstractFallbackTransactionAttributeSource#getTransactionAttribute获取 transactionAttributetransaction.interceptor.TransactionAspectSupport#determineTransactionManager 获取事务管理器transaction.interceptor.DefaultTransactionAttribute#getQualifiertransaction.interceptor.TransactionAspectSupport#getTransactionManagerutil.ConcurrentReferenceHashMap#get缓存获取 tmbeans.factory.support.DefaultListableBeanFactory#getBean 缓存没有,则通过 beanFactory 获取事务管理器 beanutil.ConcurrentReferenceHashMap#putIfAbsent 缓存事务管理器transaction.interceptor.TransactionAspectSupport#asPlatformTransactionManager 将 tm 转成 PlatformTransactionManager 类型transaction.interceptor.TransactionAspectSupport#methodIdentification 获取方法名标识transaction.interceptor.TransactionAspectSupport#methodIdentificationtransaction.interceptor.DefaultTransactionAttribute#getDescriptortransaction.interceptor.TransactionAspectSupport#createTransactionIfNecessary 创建事务transaction.support.DefaultTransactionDefinition#getNametransaction.support.AbstractPlatformTransactionManager#getTransaction 通过 tm 获取事务jdbc.datasource.DataSourceTransactionManager#doGetTransaction 创建 DataSourceTransactionObject 对象jdbc.datasource.JdbcTransactionObjectSupport#setSavepointAllowedjdbc.datasource.DataSourceTransactionManager#obtainDataSource 获取 dataSourcetransaction.support.TransactionSynchronizationManager#getResourcejdbc.datasource.DataSourceTransactionManager.DataSourceTransactionObject#setConnectionHolderjdbc.datasource.DataSourceTransactionManager#isExistingTransaction 通过判断 connectionHolder 是否为空判断是否在事务中jdbc.datasource.JdbcTransactionObjectSupport#hasConnectionHoldertransaction.support.DelegatingTransactionDefinition#getTimeout获取超时时间transaction.support.DelegatingTransactionDefinition#getPropagationBehavior获取传播属性transaction.support.AbstractPlatformTransactionManager#suspend 当前如果有事务挂起事务,根据传播行为决定transaction.support.TransactionSynchronizationManager#isSynchronizationActivetransaction.support.AbstractPlatformTransactionManager#startTransaction 开启事务transaction.support.AbstractPlatformTransactionManager#getTransactionSynchronizationtransaction.support.AbstractPlatformTransactionManager#newTransactionStatus 创建 DefaultTransactionStatusjdbc.datasource.DataSourceTransactionManager#doBegin 开启事务jdbc.datasource.JdbcTransactionObjectSupport#hasConnectionHolderjdbc.datasource.DataSourceTransactionManager#obtainDataSource 获取 dataSource,创建 connectionjdbc.datasource.DataSourceTransactionManager.DataSourceTransactionObject#setConnectionHolder 将 connection 包成 holder 塞到 DataSourceTransactionObject 里jdbc.datasource.JdbcTransactionObjectSupport#setConnectionHoldertransaction.support.ResourceHolderSupport#setSynchronizedWithTransactionjdbc.datasource.ConnectionHolder#getConnectionjdbc.datasource.DataSourceUtils#prepareConnectionForTransaction 连接做准备工作,比如是否要设置 readonly,隔离级别jdbc.datasource.JdbcTransactionObjectSupport#setPreviousIsolationLevel 塞值jdbc.datasource.JdbcTransactionObjectSupport#setReadOnly 塞值com.mysql.cj.jdbc.ConnectionImpl#getAutoCommit 如果物理连接是自动提交 autoCommit=truejdbc.datasource.DataSourceTransactionManager.DataSourceTransactionObject#setMustRestoreAutoCommit 设置DataSourceTransactionObject属性,后面需要恢复autoCommit值com.mysql.cj.jdbc.ConnectionImpl#setAutoCommit 设置 autoCommit为false,非自动提交jdbc.datasource.DataSourceTransactionManager#prepareTransactionalConnectionjdbc.datasource.ConnectionHolder#setTransactionActive 设置事务 active 状态transaction.support.AbstractPlatformTransactionManager#determineTimeout 设置事务超时时间transaction.support.TransactionSynchronizationManager#bindResource 将物理连接和当前线程绑定,threadLocal-> map<dataSource, connectionHolder>transaction.support.AbstractPlatformTransactionManager#prepareSynchronization 向TransactionSynchronizationManager里设置隔离级别,readonly等属性transaction.support.DelegatingTransactionDefinition#getIsolationLeveltransaction.support.TransactionSynchronizationManager#setCurrentTransactionIsolationLevel 设置隔离级别transaction.support.DelegatingTransactionDefinition#isReadOnlytransaction.support.TransactionSynchronizationManager#setCurrentTransactionReadOnly 设置 readonlytransaction.support.TransactionSynchronizationManager#setCurrentTransactionNametransaction.support.TransactionSynchronizationManager#initSynchronizationtransaction.interceptor.TransactionAspectSupport#prepareTransactionInfo 将 transactionInfo 和当前线程绑定transaction.interceptor.TransactionAspectSupport.TransactionInfo#newTransactionStatustransaction.interceptor.TransactionAspectSupport.TransactionInfo#bindToThreadaop.framework.CglibAopProxy.CglibMethodInvocation#proceed 调用目标方法aop.framework.ReflectiveMethodInvocation#proceedaop.framework.CglibAopProxy.CglibMethodInvocation#invokeJoinpointcglib.proxy.MethodProxy#invokecom.zc.example.service.impl.OrderServiceImpl$$FastClassBySpringCGLIB$$a1c48f40#invoke通过cglib代理类调用目标方法com.zc.example.service.impl.OrderServiceImpl#saveFailedtransaction.interceptor.TransactionAspectSupport#completeTransactionAfterThrowing 事务异常场景处理transaction.interceptor.TransactionAspectSupport.TransactionInfo#getTransactionStatustransaction.interceptor.DelegatingTransactionAttribute#rollbackOn 判断异常是否需要回滚transaction.interceptor.RuleBasedTransactionAttribute#rollbackOntransaction.support.AbstractPlatformTransactionManager#rollback 如果需要回滚,则执行回滚transaction.support.AbstractPlatformTransactionManager#processRollback 处理回滚transaction.support.AbstractPlatformTransactionManager#triggerBeforeCompletion 前置处理transaction.support.DefaultTransactionStatus#isNewSynchronizationtransaction.support.TransactionSynchronizationUtils#triggerBeforeCompletiontransaction.support.TransactionSynchronizationManager#getSynchronizationstransaction.support.TransactionSynchronizationManager#unbindResourcejdbc.datasource.DataSourceUtils#releaseConnectionjdbc.datasource.DataSourceTransactionManager#doRollback 执行回滚操作transaction.support.DefaultTransactionStatus#getTransactionjdbc.datasource.JdbcTransactionObjectSupport#getConnectionHolderjdbc.datasource.ConnectionHolder#getConnection获取物理连接,执行回滚操作jdbc.datasource.SimpleConnectionHandle#getConnection 获取物理连接con.rollback() 通过物理连接执行回滚transaction.support.AbstractPlatformTransactionManager#triggerAfterCompletion 后置处理transaction.support.TransactionSynchronizationManager#getSynchronizationstransaction.support.TransactionSynchronizationManager#clearSynchronizationtransaction.support.AbstractPlatformTransactionManager#invokeAfterCompletiontransaction.support.AbstractPlatformTransactionManager#cleanupAfterCompletion 后置清理transaction.support.AbstractTransactionStatus#setCompletedtransaction.support.TransactionSynchronizationManager#clear 清理TransactionSynchronizationManager里的threadLocal信息jdbc.datasource.DataSourceTransactionManager#doCleanupAfterCompletion 执行后置清理jdbc.datasource.DataSourceTransactionManager#obtainDataSourcetransaction.support.TransactionSynchronizationManager#unbindResource 清理当前线程threadLocal绑定的dataSourcejdbc.datasource.JdbcTransactionObjectSupport#getConnectionHolderjdbc.datasource.DataSourceTransactionManager.DataSourceTransactionObject#isMustRestoreAutoCommit 判断是否需要重置autoCommit值con.setAutoCommit(true)重置autoCommitjdbc.datasource.DataSourceUtils#resetConnectionAfterTransaction 连接重置操作jdbc.datasource.DataSourceUtils#releaseConnection 将连接关闭放回连接池jdbc.datasource.DataSourceUtils#doReleaseConnectionjdbc.datasource.DataSourceUtils#doCloseConnectionjdbc.datasource.ConnectionHolder#clear 清理txObject.connectionHolder里的信息transaction.interceptor.TransactionAspectSupport#cleanupTransactionInfo 清理transactionInfoHoldertransaction.interceptor.TransactionAspectSupport.TransactionInfo#restoreThreadLocalStatus