Spring 事务实现

Spring 事务使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
@Transactional注解配置项
事务传播行为
PROPAGATION_REQUIRED
当前方法必须在事务中,没有就创建,有就加入。
PROPAGATION_SUPPORTS
有事务就加入,没有就以非事务方式执行。
PROPAGATION_MANDATORY
有事务就加入,没有就抛出异常。
PROPAGATION_REQUIRES_NEW
永远创建新事务执行,之前若有事务则挂起之前的事务。
PROPAGATION_NOT_SUPPORTED
以非事务方式执行。之前若有事务则挂起之前的事务。
PROPAGATION_NEVER
以非事务方式执行。之前若有事务则抛出异常。
PROPAGATION_NESTED
当前若有事务,则在嵌套事务内执行。如果当前没有事务,则按 REQUIRED 属性执行。
事务隔离级别
readOnly设置
超时时间
异常回滚设置
rollbackFor
rollbackForClassName
noRollbackFor
noRollbackForClassName

Spring 事务实现

相关类

总体流程

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
启动阶段
创建代理对象(参见AOP逻辑)
获取切面列表
创建aop代理对象
事务执行
获取事务属性
获取事务管理器,创建事务
创建物理连接
autoCommit等连接属性设置
物理连接和当前线程绑定
调用目标方法,执行业务逻辑
回滚/提交事务
前置处理
物理连接执行rollback/commit操作
后置处理
后置清理
清理threadLocal
重置autoCommit
关闭连接
重置 connectionHolder

启动阶段创建代理对象逻辑

参考之前写的 Spring AOP 实现。
启动阶段创建代理对象逻辑

执行阶段调用链路

事务执行阶段,会通过启动阶段生成的代理类调用目标方法,在此之前通过 TransactionAspectSupport 处理自动开启事务/提交事务等逻辑。调用链路如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
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<dataSource, connectionHolder>
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