@Transactional注解配置项
事务传播行为
PROPAGATION_REQUIRED
当前方法必须在事务中,没有就创建,有就加入。
PROPAGATION_SUPPORTS
有事务就加入,没有就以非事务方式执行。
PROPAGATION_MANDATORY
有事务就加入,没有就抛出异常。
PROPAGATION_REQUIRES_NEW
永远创建新事务执行,之前若有事务则挂起之前的事务。
PROPAGATION_NOT_SUPPORTED
以非事务方式执行。之前若有事务则挂起之前的事务。
PROPAGATION_NEVER
以非事务方式执行。之前若有事务则抛出异常。
PROPAGATION_NESTED
当前若有事务,则在嵌套事务内执行。如果当前没有事务,则按 REQUIRED 属性执行。
事务隔离级别
readOnly设置
超时时间
异常回滚设置
rollbackFor
rollbackForClassName
noRollbackFor
noRollbackForClassName
启动阶段
创建代理对象(参见AOP逻辑)
获取切面列表
创建aop代理对象
事务执行
获取事务属性
获取事务管理器,创建事务
创建物理连接
autoCommit等连接属性设置
物理连接和当前线程绑定
调用目标方法,执行业务逻辑
回滚/提交事务
前置处理
物理连接执行rollback/commit操作
后置处理
后置清理
清理threadLocal
重置autoCommit
关闭连接
重置 connectionHolder
参考我之前写的 Spring AOP 实现。
启动阶段创建代理对象逻辑
事务执行阶段,会通过启动阶段生成的代理类调用目标方法,在此之前通过 TransactionAspectSupport 处理自动开启事务/提交事务等逻辑。调用链路如下:
aop.framework.CglibAopProxy.CglibMethodInvocation#proceed
事务处理流程
aop.framework.ReflectiveMethodInvocation#proceed
transaction.interceptor.TransactionInterceptor#invoke
事务拦截器处理
transaction.interceptor.TransactionAspectSupport#invokeWithinTransaction
事务内调用目标方法
transaction.interceptor.TransactionAspectSupport#getTransactionAttributeSource
transaction.interceptor.AbstractFallbackTransactionAttributeSource#getTransactionAttribute
获取 transactionAttribute
transaction.interceptor.TransactionAspectSupport#determineTransactionManager
获取事务管理器
transaction.interceptor.DefaultTransactionAttribute#getQualifier
transaction.interceptor.TransactionAspectSupport#getTransactionManager
util.ConcurrentReferenceHashMap#get
缓存获取 tm
beans.factory.support.DefaultListableBeanFactory#getBean
缓存没有,则通过 beanFactory 获取事务管理器 bean
util.ConcurrentReferenceHashMap#putIfAbsent
缓存事务管理器
transaction.interceptor.TransactionAspectSupport#asPlatformTransactionManager
将 tm 转成 PlatformTransactionManager 类型
transaction.interceptor.TransactionAspectSupport#methodIdentification
获取方法名标识
transaction.interceptor.TransactionAspectSupport#methodIdentification
transaction.interceptor.DefaultTransactionAttribute#getDescriptor
transaction.interceptor.TransactionAspectSupport#createTransactionIfNecessary
创建事务
transaction.support.DefaultTransactionDefinition#getName
transaction.support.AbstractPlatformTransactionManager#getTransaction
通过 tm 获取事务
jdbc.datasource.DataSourceTransactionManager#doGetTransaction
创建 DataSourceTransactionObject 对象
jdbc.datasource.JdbcTransactionObjectSupport#setSavepointAllowed
jdbc.datasource.DataSourceTransactionManager#obtainDataSource
获取 dataSource
transaction.support.TransactionSynchronizationManager#getResource
jdbc.datasource.DataSourceTransactionManager.DataSourceTransactionObject#setConnectionHolder
jdbc.datasource.DataSourceTransactionManager#isExistingTransaction
通过判断 connectionHolder 是否为空判断是否在事务中
jdbc.datasource.JdbcTransactionObjectSupport#hasConnectionHolder
transaction.support.DelegatingTransactionDefinition#getTimeout
获取超时时间
transaction.support.DelegatingTransactionDefinition#getPropagationBehavior
获取传播属性
transaction.support.AbstractPlatformTransactionManager#suspend
当前如果有事务挂起事务,根据传播行为决定
transaction.support.TransactionSynchronizationManager#isSynchronizationActive
transaction.support.AbstractPlatformTransactionManager#startTransaction
开启事务
transaction.support.AbstractPlatformTransactionManager#getTransactionSynchronization
transaction.support.AbstractPlatformTransactionManager#newTransactionStatus
创建 DefaultTransactionStatus
jdbc.datasource.DataSourceTransactionManager#doBegin
开启事务
jdbc.datasource.JdbcTransactionObjectSupport#hasConnectionHolder
jdbc.datasource.DataSourceTransactionManager#obtainDataSource
获取 dataSource,创建 connection
jdbc.datasource.DataSourceTransactionManager.DataSourceTransactionObject#setConnectionHolder
将 connection 包成 holder 塞到 DataSourceTransactionObject 里
jdbc.datasource.JdbcTransactionObjectSupport#setConnectionHolder
transaction.support.ResourceHolderSupport#setSynchronizedWithTransaction
jdbc.datasource.ConnectionHolder#getConnection
jdbc.datasource.DataSourceUtils#prepareConnectionForTransaction
连接做准备工作,比如是否要设置 readonly,隔离级别
jdbc.datasource.JdbcTransactionObjectSupport#setPreviousIsolationLevel 塞值
jdbc.datasource.JdbcTransactionObjectSupport#setReadOnly 塞值
com.mysql.cj.jdbc.ConnectionImpl#getAutoCommit
如果物理连接是自动提交 autoCommit=true
jdbc.datasource.DataSourceTransactionManager.DataSourceTransactionObject#setMustRestoreAutoCommit
设置DataSourceTransactionObject属性,后面需要恢复autoCommit值
com.mysql.cj.jdbc.ConnectionImpl#setAutoCommit
设置 autoCommit为false,非自动提交
jdbc.datasource.DataSourceTransactionManager#prepareTransactionalConnection
jdbc.datasource.ConnectionHolder#setTransactionActive
设置事务 active 状态
transaction.support.AbstractPlatformTransactionManager#determineTimeout
设置事务超时时间
transaction.support.TransactionSynchronizationManager#bindResource
将物理连接和当前线程绑定,threadLocal-> map
transaction.support.AbstractPlatformTransactionManager#prepareSynchronization
向TransactionSynchronizationManager里设置隔离级别,readonly等属性
transaction.support.DelegatingTransactionDefinition#getIsolationLevel
transaction.support.TransactionSynchronizationManager#setCurrentTransactionIsolationLevel
设置隔离级别
transaction.support.DelegatingTransactionDefinition#isReadOnly
transaction.support.TransactionSynchronizationManager#setCurrentTransactionReadOnly
设置 readonly
transaction.support.TransactionSynchronizationManager#setCurrentTransactionName
transaction.support.TransactionSynchronizationManager#initSynchronization
transaction.interceptor.TransactionAspectSupport#prepareTransactionInfo
将 transactionInfo 和当前线程绑定
transaction.interceptor.TransactionAspectSupport.TransactionInfo#newTransactionStatus
transaction.interceptor.TransactionAspectSupport.TransactionInfo#bindToThread
aop.framework.CglibAopProxy.CglibMethodInvocation#proceed
调用目标方法
aop.framework.ReflectiveMethodInvocation#proceed
aop.framework.CglibAopProxy.CglibMethodInvocation#invokeJoinpoint
cglib.proxy.MethodProxy#invoke
com.zc.example.service.impl.OrderServiceImpl$$FastClassBySpringCGLIB$$a1c48f40#invoke
通过cglib代理类调用目标方法
com.zc.example.service.impl.OrderServiceImpl#saveFailed
transaction.interceptor.TransactionAspectSupport#completeTransactionAfterThrowing
事务异常场景处理
transaction.interceptor.TransactionAspectSupport.TransactionInfo#getTransactionStatus
transaction.interceptor.DelegatingTransactionAttribute#rollbackOn
判断异常是否需要回滚
transaction.interceptor.RuleBasedTransactionAttribute#rollbackOn
transaction.support.AbstractPlatformTransactionManager#rollback
如果需要回滚,则执行回滚
transaction.support.AbstractPlatformTransactionManager#processRollback
处理回滚
transaction.support.AbstractPlatformTransactionManager#triggerBeforeCompletion
前置处理
transaction.support.DefaultTransactionStatus#isNewSynchronization
transaction.support.TransactionSynchronizationUtils#triggerBeforeCompletion
transaction.support.TransactionSynchronizationManager#getSynchronizations
transaction.support.TransactionSynchronizationManager#unbindResource
jdbc.datasource.DataSourceUtils#releaseConnection
jdbc.datasource.DataSourceTransactionManager#doRollback
执行回滚操作
transaction.support.DefaultTransactionStatus#getTransaction
jdbc.datasource.JdbcTransactionObjectSupport#getConnectionHolder
jdbc.datasource.ConnectionHolder#getConnection
获取物理连接,执行回滚操作
jdbc.datasource.SimpleConnectionHandle#getConnection
获取物理连接
con.rollback()
通过物理连接执行回滚
transaction.support.AbstractPlatformTransactionManager#triggerAfterCompletion
后置处理
transaction.support.TransactionSynchronizationManager#getSynchronizations
transaction.support.TransactionSynchronizationManager#clearSynchronization
transaction.support.AbstractPlatformTransactionManager#invokeAfterCompletion
transaction.support.AbstractPlatformTransactionManager#cleanupAfterCompletion
后置清理
transaction.support.AbstractTransactionStatus#setCompleted
transaction.support.TransactionSynchronizationManager#clear
清理TransactionSynchronizationManager里的threadLocal信息
jdbc.datasource.DataSourceTransactionManager#doCleanupAfterCompletion
执行后置清理
jdbc.datasource.DataSourceTransactionManager#obtainDataSource
transaction.support.TransactionSynchronizationManager#unbindResource
清理当前线程threadLocal绑定的dataSource
jdbc.datasource.JdbcTransactionObjectSupport#getConnectionHolder
jdbc.datasource.DataSourceTransactionManager.DataSourceTransactionObject#isMustRestoreAutoCommit
判断是否需要重置autoCommit值
con.setAutoCommit(true)
重置autoCommit
jdbc.datasource.DataSourceUtils#resetConnectionAfterTransaction
连接重置操作
jdbc.datasource.DataSourceUtils#releaseConnection
将连接关闭放回连接池
jdbc.datasource.DataSourceUtils#doReleaseConnection
jdbc.datasource.DataSourceUtils#doCloseConnection
jdbc.datasource.ConnectionHolder#clear
清理txObject.connectionHolder里的信息
transaction.interceptor.TransactionAspectSupport#cleanupTransactionInfo
清理transactionInfoHolder
transaction.interceptor.TransactionAspectSupport.TransactionInfo#restoreThreadLocalStatus