1. 目录

[TOC]

2. 说明

@Transactional为spring提供的申明式事务管理,开发者可以很快速的开启事务,同时,其自带了事务管理,可以在事务结束时自行提交或回滚,大大减少了程序编码,同时也避免了IO连接泄露
同时,@Transactional 还提供了传播特性和隔离级别,更好的扩展了程序中可能出现的场景

3. 依赖分析

4. 源码分析

4.1. 自动配置事务管理器

spring项目中需要在xml文件中配置事务管理器,而springboot中通过@EnableTransactionManagement来开启事务生效,新版本中已经不需要@EnableTransactionManagement了,直接通过TransactionAutoConfiguration类来进行自动配置,注入需要的类。

4.1.1. 加载TransactionAutoConfiguration

springboot自动化配置会扫描配置的configuration,加载主要为spring boot的相关流程逻辑。
其扫描先不做分析,从ConfigurationClassParser$DeferredImportSelectorGroupingHandler分析加载,此类就是扫描自动配置类的,其中groupings属性保存了所有的配置类的信息,如图

autoconfiguration

比如我们常见的
org.springframework.boot.autoconfigure.aop.AopAutoConfiguration
org.springframework.boot.autoconfigure.context.ConfigurationPropertiesAutoConfiguration
org.springframework.boot.autoconfigure.jdbc.JdbcTemplateAutoConfiguration
org.springframework.boot.autoconfigure.task.TaskSchedulingAutoConfiguration
org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration
org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration
我们今天分析的TransactionAutoConfiguration也在其中
首先我们看processGroupImports()方法,会将每一个配置configuration进行processImports()处理,

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
class ConfigurationClassParser$DeferredImportSelectorGroupingHandler{
//处理导入组
public void processGroupImports() {
for (DeferredImportSelectorGrouping grouping : this.groupings.values()) {
Predicate<String> exclusionFilter = grouping.getCandidateFilter();
//循环配置类
grouping.getImports().forEach(entry -> {
ConfigurationClass configurationClass = this.configurationClasses.get(entry.getMetadata());
try {
//处理配置
processImports(configurationClass, asSourceClass(configurationClass, exclusionFilter),
Collections.singleton(asSourceClass(entry.getImportClassName(), exclusionFilter)),
exclusionFilter, false);
}
catch (BeanDefinitionStoreException ex) {
throw ex;
}
catch (Throwable ex) {
throw new BeanDefinitionStoreException(
"Failed to process import candidates for configuration class [" +
configurationClass.getMetadata().getClassName() + "]", ex);
}
});
}
}
}

processImports()处理如下,此方法很长,且好些看不懂,我们看主要的

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
class ConfigurationClassParser$DeferredImportSelectorGroupingHandler{
private void processImports(ConfigurationClass configClass, SourceClass currentSourceClass,
Collection<SourceClass> importCandidates, Predicate<String> exclusionFilter,
boolean checkForCircularImports) {
if (checkForCircularImports && isChainedImportOnStack(configClass)) {
//......
}
else {
this.importStack.push(configClass);
try {
for (SourceClass candidate : importCandidates) {
if (candidate.isAssignable(ImportSelector.class)) {
//......
//执行handler
if (selector instanceof DeferredImportSelector) {
this.deferredImportSelectorHandler.handle(configClass, (DeferredImportSelector) selector);
}
//继续加载自己引入的Import
else {
String[] importClassNames = selector.selectImports(currentSourceClass.getMetadata());
//本方法递归 继续引入
processImports(configClass, currentSourceClass, importSourceClasses, exclusionFilter, false);
}

}
else if (candidate.isAssignable(ImportBeanDefinitionRegistrar.class)) {
//......
//添加 ImportBeanDefinitionRegistrar
configClass.addImportBeanDefinitionRegistrar(registrar, currentSourceClass.getMetadata());
}
else {
//刚开始走这里,注册Import,加载TransactionAutoConfiguration的配置类
this.importStack.registerImport(
currentSourceClass.getMetadata(), candidate.getMetadata().getClassName());
//处理配置类
processConfigurationClass(candidate.asConfigClass(configClass), exclusionFilter);
}
}
}
//简化
catch Exception ex) {
throw ex;
}
finally {
this.importStack.pop();
}
}
}
}
  1. this.importStack.registerImport
    主要将org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration.class的配置类和内部类的配置类加载进来
    registerImport

  2. processConfigurationClass() 处理配置类

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    class ConfigurationClassParser$DeferredImportSelectorGroupingHandler{
    protected void processConfigurationClass(ConfigurationClass configClass, Predicate<String> filter) throws IOException {
    //......省略
    do {
    //执行处理配置
    sourceClass = doProcessConfigurationClass(configClass, sourceClass, filter);
    }
    while (sourceClass != null);
    //缓存
    this.configurationClasses.put(configClass, configClass);
    }
    }
  3. doProcessConfigurationClass() 执行处理配置
    此类为处理的主要类了

    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
    class ConfigurationClassParser$DeferredImportSelectorGroupingHandler{
    protected final SourceClass doProcessConfigurationClass(
    ConfigurationClass configClass, SourceClass sourceClass, Predicate<String> filter)
    throws IOException {

    if (configClass.getMetadata().isAnnotated(Component.class.getName())) {
    //将内部的配置类初始化,此处时代码递归调用,没有子类就结束了
    processMemberClasses(configClass, sourceClass, filter);
    }
    for (AnnotationAttributes propertySource : AnnotationConfigUtils.attributesForRepeatable(
    sourceClass.getMetadata(), PropertySources.class,
    org.springframework.context.annotation.PropertySource.class)) {
    //...... 略
    }

    //这里是处理Imports类的主要地方,即@Import()注解对应的类,这里
    //EnableTransactionManagementConfiguration会调用加载CglibAutoProxyConfiguration配置类,再加载其中的@Import(TransactionManagementConfigurationSelector.class)
    processImports(configClass, sourceClass, getImports(sourceClass), filter, true);

    //后面暂时不管,主要前面加载Imports 带入
    // Process any @ImportResource annotations
    AnnotationAttributes importResource =
    AnnotationConfigUtils.attributesFor(sourceClass.getMetadata(), ImportResource.class);
    if (importResource != null) {
    String[] resources = importResource.getStringArray("locations");
    Class<? extends BeanDefinitionReader> readerClass = importResource.getClass("reader");
    for (String resource : resources) {
    String resolvedResource = this.environment.resolveRequiredPlaceholders(resource);
    configClass.addImportedResource(resolvedResource, readerClass);
    }
    }

    Set<MethodMetadata> beanMethods = retrieveBeanMethodMetadata(sourceClass);
    for (MethodMetadata methodMetadata : beanMethods) {
    configClass.addBeanMethod(new BeanMethod(methodMetadata, configClass));
    }

    processInterfaces(configClass, sourceClass);

    if (sourceClass.getMetadata().hasSuperClass()) {
    String superclass = sourceClass.getMetadata().getSuperClassName();
    if (superclass != null && !superclass.startsWith("java") &&
    !this.knownSuperclasses.containsKey(superclass)) {
    this.knownSuperclasses.put(superclass, configClass);
    return sourceClass.getSuperClass();
    }
    }
    return null;
    }
    }

加载如图

EnableTransactionManagementConfiguration

具体的关于TransactionAutoConfiguration见后文

加载完成后在外层将获取到的信息加入到ConfigurationClassParser.configurationClasses
this.configurationClasses.put(configClass, configClass)

4.1.2. TransactionAutoConfiguration自动配置类

由前面分析我们已经得到了springboot加载到配置类TransactionAutoConfiguration,本小结主要分析配置类的配置

4.1.2.1. 配置类TransactionAutoConfiguration

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
//开启配置
@Configuration(proxyBeanMethods = false)
//当配置了PlatformTransactionManager事务管理器时生效
@ConditionalOnClass(PlatformTransactionManager.class)
//在数据源配置之后加载此配置
@AutoConfigureAfter({ JtaAutoConfiguration.class, HibernateJpaAutoConfiguration.class,
DataSourceTransactionManagerAutoConfiguration.class, Neo4jDataAutoConfiguration.class })
//application.properties中的配置信息加载
@EnableConfigurationProperties(TransactionProperties.class)
public class TransactionAutoConfiguration {

@Bean
@ConditionalOnMissingBean
//自定义配置,有自定义需求时配置此类的信息
public TransactionManagerCustomizers platformTransactionManagerCustomizers(
ObjectProvider<PlatformTransactionManagerCustomizer<?>> customizers) {
return new TransactionManagerCustomizers(customizers.orderedStream().collect(Collectors.toList()));
}

@Bean
@ConditionalOnMissingBean
@ConditionalOnSingleCandidate(ReactiveTransactionManager.class)
//不知道干嘛的,先不管
public TransactionalOperator transactionalOperator(ReactiveTransactionManager transactionManager) {
return TransactionalOperator.create(transactionManager);
}

@Configuration(proxyBeanMethods = false)
@ConditionalOnSingleCandidate(PlatformTransactionManager.class)
//事务模板配置
public static class TransactionTemplateConfiguration {

@Bean
@ConditionalOnMissingBean(TransactionOperations.class)
public TransactionTemplate transactionTemplate(PlatformTransactionManager transactionManager) {
return new TransactionTemplate(transactionManager);
}

}

@Configuration(proxyBeanMethods = false)
@ConditionalOnBean(TransactionManager.class)
@ConditionalOnMissingBean(AbstractTransactionManagementConfiguration.class)
//开启事务管理器配置,此处很重要,会开启子类JdkDynamicAutoProxyConfiguration和CglibAutoProxyConfiguration配置中的其中一个,
//默认开启CglibAutoProxyConfiguration
public static class EnableTransactionManagementConfiguration {

@Configuration(proxyBeanMethods = false)
@EnableTransactionManagement(proxyTargetClass = false)
@ConditionalOnProperty(prefix = "spring.aop", name = "proxy-target-class", havingValue = "false",
matchIfMissing = false)
public static class JdkDynamicAutoProxyConfiguration {

}

@Configuration(proxyBeanMethods = false)
@EnableTransactionManagement(proxyTargetClass = true)
@ConditionalOnProperty(prefix = "spring.aop", name = "proxy-target-class", havingValue = "true",
matchIfMissing = true)
public static class CglibAutoProxyConfiguration {

}

}

}

4.1.2.2. 配置类@EnableTransactionManagement

前面我们已经知道会加载到@EnableTransactionManagement,并且会选择JDKCGLIB其中一个做代理
接下来我们继续分析@EnableTransactionManagement

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
//引入TransactionManagementConfigurationSelector,此selector会真正创建事务管理器相关的东西
@Import(TransactionManagementConfigurationSelector.class)
public @interface EnableTransactionManagement {
//是否是cglib代理,当mode为PROXY即动态代理时生效
boolean proxyTargetClass() default false;
//增强模式,默认为代理模式,也可以配置aspectj,aspectj支持更高级的配置
AdviceMode mode() default AdviceMode.PROXY;
//事务通知的顺序,不管这个
int order() default Ordered.LOWEST_PRECEDENCE;

}

以上是一个全局配置,一般不用配默认就是此种,要配置的话根据spring.aop相关配置属性定义

apo

4.1.2.2.1. TransactionManagementConfigurationSelector 选择配置
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
public class TransactionManagementConfigurationSelector extends AdviceModeImportSelector<EnableTransactionManagement> {
//父类方法,获取到选择器中对应的类
public final String[] selectImports(AnnotationMetadata importingClassMetadata) {
Class<?> annType = GenericTypeResolver.resolveTypeArgument(getClass(), AdviceModeImportSelector.class);
Assert.state(annType != null, "Unresolvable type argument for AdviceModeImportSelector");

AnnotationAttributes attributes = AnnotationConfigUtils.attributesFor(importingClassMetadata, annType);
if (attributes == null) {
throw new IllegalArgumentException(String.format(
"@%s is not present on importing class '%s' as expected",
annType.getSimpleName(), importingClassMetadata.getClassName()));
}

AdviceMode adviceMode = attributes.getEnum(getAdviceModeAttributeName());
String[] imports = selectImports(adviceMode);
if (imports == null) {
throw new IllegalArgumentException("Unknown AdviceMode: " + adviceMode);
}
return imports;
}
//选择类,获取到对应的需要初始化的类
@Override
protected String[] selectImports(AdviceMode adviceMode) {
switch (adviceMode) {
case PROXY:
return new String[] {AutoProxyRegistrar.class.getName(),
ProxyTransactionManagementConfiguration.class.getName()};
case ASPECTJ:
return new String[] {determineTransactionAspectClass()};
default:
return null;
}
}

private String determineTransactionAspectClass() {
return (ClassUtils.isPresent("javax.transaction.Transactional", getClass().getClassLoader()) ?
TransactionManagementConfigUtils.JTA_TRANSACTION_ASPECT_CONFIGURATION_CLASS_NAME :
TransactionManagementConfigUtils.TRANSACTION_ASPECT_CONFIGURATION_CLASS_NAME);
}

}

此类主要将需要配置的额外的初始化类配置类ProxyTransactionManagementConfiguration获取到importStack中,后续初始化配置此类,

4.1.2.3. ProxyTransactionManagementConfiguration 动态代理配置类

此类配置了TransactionInterceptor事务拦截器和TransactionAttributeSource

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
@Configuration(proxyBeanMethods = false)
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public class ProxyTransactionManagementConfiguration extends AbstractTransactionManagementConfiguration {

@Bean(name = TransactionManagementConfigUtils.TRANSACTION_ADVISOR_BEAN_NAME)
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public BeanFactoryTransactionAttributeSourceAdvisor transactionAdvisor(
TransactionAttributeSource transactionAttributeSource, TransactionInterceptor transactionInterceptor) {

BeanFactoryTransactionAttributeSourceAdvisor advisor = new BeanFactoryTransactionAttributeSourceAdvisor();
advisor.setTransactionAttributeSource(transactionAttributeSource);
advisor.setAdvice(transactionInterceptor);
if (this.enableTx != null) {
advisor.setOrder(this.enableTx.<Integer>getNumber("order"));
}
return advisor;
}

@Bean
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public TransactionAttributeSource transactionAttributeSource() {
return new AnnotationTransactionAttributeSource();
}

@Bean
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public TransactionInterceptor transactionInterceptor(TransactionAttributeSource transactionAttributeSource) {
TransactionInterceptor interceptor = new TransactionInterceptor();
interceptor.setTransactionAttributeSource(transactionAttributeSource);
if (this.txManager != null) {
interceptor.setTransactionManager(this.txManager);
}
return interceptor;
}

}

TransactionInterceptor事务拦截器,被代理的@Transactional都会加载动态代理,就会经过此拦截器,也就是其实他是具体处理事务的。
TransactionAttributeSource则为处理注解属性相关的类,保存了初始化的事务的传播特性、隔离级别、回滚等,这里更像一个Map容器,主要属性在其内部的TransactionAttribute

4.2. 应用使用

我们知道,加了@Transactional的实际上在spring的容器中已经是代理过后的bean了,那么从注入的地方调用代码实际上首先会进入到代理类CglibAopProxy$DynamicAdvisedInterceptor

1
2
3
4
5
6
7
8

@Autowired
//此service即为被代理之后的对象,
UucsUserService uucsUserService;
@Test
public void t3(){
UucsUser user = uucsUserService.getUser(1);
}

调用进入代理对象DynamicAdvisedInterceptorintercept()方法

看一下进入时proxy

proxy

可以发现此动态代理是多层代理,这也符合实际情况,我们只关注DynamicAdvisedInterceptor本身的流程即可,处理到其他的代理时无需再关注
再看源码

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
class CglibAopProxy$DynamicAdvisedInterceptor{
@Override
@Nullable
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
Object oldProxy = null;
boolean setProxyContext = false;
Object target = null;
TargetSource targetSource = this.advised.getTargetSource();
try {
//不走此处
if (this.advised.exposeProxy) {
oldProxy = AopContext.setCurrentProxy(proxy);
setProxyContext = true;
}
target = targetSource.getTarget();
Class<?> targetClass = (target != null ? target.getClass() : null);
//主要关注这里,得到TransactionInterceptor,即我们之前配置的
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
Object retVal;
if (chain.isEmpty() && Modifier.isPublic(method.getModifiers())) {
Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
retVal = methodProxy.invoke(target, argsToUse);
}
else {
//走这里逻辑 proceed()开始执行处理,详见下面<1>
retVal = new CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy).proceed();
}
retVal = processReturnType(proxy, target, method, retVal);
return retVal;
}
finally {
if (target != null && !targetSource.isStatic()) {
targetSource.releaseTarget(target);
}
if (setProxyContext) {
// Restore old proxy.
AopContext.setCurrentProxy(oldProxy);
}
}
}
}

<1> 其中CglibMethodInvocation.proceed()是典型的代理的代码,代理相关可以直接跳过,在方法中得到实际的处理类TransactionInterceptor,再执行反射((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this)调用进入TransactionInterceptor#invoke()方法

4.2.1. TransactionInterceptor 事务拦截器

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
public class TransactionInterceptor{
public Object invoke(MethodInvocation invocation) throws Throwable {
//获取到原始的类,即代理前的实际类,因为业务处理最后还是在原来的类上
Class<?> targetClass = (invocation.getThis() != null ? AopUtils.getTargetClass(invocation.getThis()) : null);

return invokeWithinTransaction(invocation.getMethod(), targetClass, invocation::proceed);
}
//执行事务方法,这里很长
protected Object invokeWithinTransaction(Method method, @Nullable Class<?> targetClass,
final InvocationCallback invocation) throws Throwable {

// 获取到配置的TransactionAttributeSource
TransactionAttributeSource tas = getTransactionAttributeSource();
//拿到事务属性,TransactionAttribute
final TransactionAttribute txAttr = (tas != null ? tas.getTransactionAttribute(method, targetClass) : null);

//拿到事务管理器,这很重要,其他的orm框架也会用到此事务管理器、
//实际拿到的为DatasourceTransactionManager,内部使用懒加载得到TransactionManager,就不看了
final TransactionManager tm = determineTransactionManager(txAttr);

//一般不走这里,不用看
if (this.reactiveAdapterRegistry != null && tm instanceof ReactiveTransactionManager) {
// ......
}
//构造PlatformTransactionManager,没干嘛,强制转换了一下
PlatformTransactionManager ptm = asPlatformTransactionManager(tm);

//得到方法 com.kewen.service.UucsUserService.getUser
final String joinpointIdentification = methodIdentification(method, targetClass, txAttr);

//ptm=DatasourceTransactionManager,一般就走这里了
if (txAttr == null || !(ptm instanceof CallbackPreferringPlatformTransactionManager)) {

//创建事务,同时这里已经把数据库连接维护好了,见下文<1>
TransactionInfo txInfo = createTransactionIfNecessary(ptm, txAttr, joinpointIdentification);

Object retVal;
try {
//执行下一个代理,若是没有代理了则执行joinPoint原对象方法,就不用看了
//在执行原方法后面可能连接数据库,持久层框架如mabatis会使用事务里面的DatasourceTrasactionManagement事务管理器,从而进一步控制或交给现有Management
retVal = invocation.proceedWithInvocation();
}
catch (Throwable ex) {
//这里处理异常、回滚事务,并抛出
completeTransactionAfterThrowing(txInfo, ex);
throw ex;
}
finally {
//从本地ThreadLocal释放TransactionInfo信息
cleanupTransactionInfo(txInfo);
}

if (retVal != null && vavrPresent && VavrDelegate.isVavrTry(retVal)) {
TransactionStatus status = txInfo.getTransactionStatus();
if (status != null && txAttr != null) {
retVal = VavrDelegate.evaluateTryFailure(retVal, txAttr, status);
}
}
//提交事务,这里面的逻辑也大部分是跟数据库连接相关的,暂时就不分析进去了
commitTransactionAfterReturning(txInfo);
return retVal;
}

else {
// ...... 一般不走这里
}
}
}

<1> TransactionInfo内容,保存到有事务的特性等
txinfo

4.2.1.1. createTransactionIfNecessary()

这里是真正开启事务的地方,为啥是ifNecessary,因为根据传播特性可能不需要开事务的
同时这里已经把数据库连接维护好了

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
public class TransactionInterceptor {

//父类TransactionAspectSupport方法
protected TransactionInfo createTransactionIfNecessary(@Nullable PlatformTransactionManager tm,
@Nullable TransactionAttribute txAttr, final String joinpointIdentification) {

// 可以理解为包装了一下,也没啥特别的
if (txAttr != null && txAttr.getName() == null) {
txAttr = new DelegatingTransactionAttribute(txAttr) {
@Override
public String getName() {
return joinpointIdentification;
}
};
}

TransactionStatus status = null;
if (txAttr != null) {
if (tm != null) {
//获取事务,内部还是比较多的,会校验传播特性和隔离级别的,开启数据库连接
status = tm.getTransaction(txAttr);
}
else {
if (logger.isDebugEnabled()) {
logger.debug("Skipping transactional joinpoint [" + joinpointIdentification +
"] because no transaction manager has been configured");
}
}
}
//
return prepareTransactionInfo(tm, txAttr, joinpointIdentification, status);
}

}
4.2.1.1.1. tm.getTranscation() 开启数据库连接
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
public class DataSourceTransactionManager{
public final TransactionStatus getTransaction(@Nullable TransactionDefinition definition)
throws TransactionException {

//没有指定此处获取默认的传播特性和隔离级别
TransactionDefinition def = (definition != null ? definition : TransactionDefinition.withDefaults());
// 获取数据库连接相关的事务配置
Object transaction = doGetTransaction();
boolean debugEnabled = logger.isDebugEnabled();
//检查给定的事务对象是否指示存在的事务(即已经启动的事务)。
//现有事务可能会挂起(在PROPAGATION_REQUIRES_NEW的情况下),或者新事务可能会参与现有事务(在PROPAGATION_REQUIRED的情况下)。默认实现返回false
if (isExistingTransaction(transaction)) {
//不走,不管里面,比较复杂
return handleExistingTransaction(def, transaction, debugEnabled);
}
//超时时间比对
if (def.getTimeout() < TransactionDefinition.TIMEOUT_DEFAULT) {
throw new InvalidTimeoutException("Invalid transaction timeout", def.getTimeout());
}

//检查是否强制开启事务,没开启则此处报错
if (def.getPropagationBehavior() == TransactionDefinition.PROPAGATION_MANDATORY) {
throw new IllegalTransactionStateException(
"No existing transaction found for transaction marked with propagation 'mandatory'");
}
//需要事务的分支
else if (def.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRED ||
def.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRES_NEW ||
def.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NESTED) {
SuspendedResourcesHolder suspendedResources = suspend(null);
try {
//开启事务
return startTransaction(def, transaction, debugEnabled, suspendedResources);
}
catch (RuntimeException | Error ex) {
resume(null, suspendedResources);
throw ex;
}
}
else {
//......不需要事务的分支,不管了这里
}
}
//开启事务
private TransactionStatus startTransaction(TransactionDefinition definition, Object transaction,
boolean debugEnabled, @Nullable SuspendedResourcesHolder suspendedResources) {

boolean newSynchronization = (getTransactionSynchronization() != SYNCHRONIZATION_NEVER);
DefaultTransactionStatus status = newTransactionStatus(
definition, transaction, true, newSynchronization, debugEnabled, suspendedResources);
//执行开始
doBegin(transaction, definition);
//准备同步信息,设置隔离级别、只读等
prepareSynchronization(status, definition);
return status;
}
//执行开始事务
@Override
protected void doBegin(Object transaction, TransactionDefinition definition) {
DataSourceTransactionObject txObject = (DataSourceTransactionObject) transaction;
Connection con = null;

try {
if (!txObject.hasConnectionHolder() ||
txObject.getConnectionHolder().isSynchronizedWithTransaction()) {
//开启连接
//**这里执行真正的打开数据了**
Connection newCon = obtainDataSource().getConnection();
if (logger.isDebugEnabled()) {
logger.debug("Acquired Connection [" + newCon + "] for JDBC transaction");
}
//设置上下文Holder
txObject.setConnectionHolder(new ConnectionHolder(newCon), true);
}

txObject.getConnectionHolder().setSynchronizedWithTransaction(true);
con = txObject.getConnectionHolder().getConnection();
//用给定的事务语义准备给定的Connection。
//数据库相关,先暂时不看了
Integer previousIsolationLevel = DataSourceUtils.prepareConnectionForTransaction(con, definition);
//传播特性
txObject.setPreviousIsolationLevel(previousIsolationLevel);
//是否只读
txObject.setReadOnly(definition.isReadOnly());
//自动提交
if (con.getAutoCommit()) {
txObject.setMustRestoreAutoCommit(true);
if (logger.isDebugEnabled()) {
logger.debug("Switching JDBC Connection [" + con + "] to manual commit");
}
con.setAutoCommit(false);
}
//设置查询前的sql语句 “SET TRANSACTION READ ONLY”
prepareTransactionalConnection(con, definition);
txObject.getConnectionHolder().setTransactionActive(true);

//设置超时
int timeout = determineTimeout(definition);
if (timeout != TransactionDefinition.TIMEOUT_DEFAULT) {
txObject.getConnectionHolder().setTimeoutInSeconds(timeout);
}

//绑定数据连接,及配置的数据库地址等,放置在ThreadLocal中
if (txObject.isNewConnectionHolder()) {
TransactionSynchronizationManager.bindResource(obtainDataSource(), txObject.getConnectionHolder());
}
}
//有异常则释放连接
catch (Throwable ex) {
if (txObject.isNewConnectionHolder()) {
DataSourceUtils.releaseConnection(con, obtainDataSource());
txObject.setConnectionHolder(null, false);
}
throw new CannotCreateTransactionException("Could not open JDBC Connection for transaction", ex);
}
}
//ThreadLocal中设置隔离级别,只读等
protected void prepareSynchronization(DefaultTransactionStatus status, TransactionDefinition definition) {
if (status.isNewSynchronization()) {
TransactionSynchronizationManager.setActualTransactionActive(status.hasTransaction());
TransactionSynchronizationManager.setCurrentTransactionIsolationLevel(
definition.getIsolationLevel() != TransactionDefinition.ISOLATION_DEFAULT ?
definition.getIsolationLevel() : null);
TransactionSynchronizationManager.setCurrentTransactionReadOnly(definition.isReadOnly());
TransactionSynchronizationManager.setCurrentTransactionName(definition.getName());
TransactionSynchronizationManager.initSynchronization();
}
}
}
4.2.1.1.2. prepareTransactionInfo() 准备事务信息

注意到这里实际上已经开了数据库连接了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class TransactionInterceptor{
//记录事务信息,封装到TransactionInfo中
protected TransactionInfo prepareTransactionInfo(@Nullable PlatformTransactionManager tm,
@Nullable TransactionAttribute txAttr, String joinpointIdentification,
@Nullable TransactionStatus status) {

TransactionInfo txInfo = new TransactionInfo(tm, txAttr, joinpointIdentification);
if (txAttr != null) {
//设置status,
txInfo.newTransactionStatus(status);
}
txInfo.bindToThread();
return txInfo;
}
}

4.2.1.2. commitTransactionAfterReturning() 提交事务

1
2
3
4
5
6
7
8
9
10
11
public class TransactionInterceptor{
protected void commitTransactionAfterReturning(@Nullable TransactionInfo txInfo) {
if (txInfo != null && txInfo.getTransactionStatus() != null) {
if (logger.isTraceEnabled()) {
logger.trace("Completing transaction for [" + txInfo.getJoinpointIdentification() + "]");
}
//主要是TransactionManager内部的操作,因此TransactionManager是相当重要的
txInfo.getTransactionManager().commit(txInfo.getTransactionStatus());
}
}
}
4.2.1.2.1. DatasourceTransactionManagement#commit() 提交事务
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
public class DatasourceTransactionManagement{
@Override
public final void commit(TransactionStatus status) throws TransactionException {
if (status.isCompleted()) {
throw new IllegalTransactionStateException(
"Transaction is already completed - do not call commit or rollback more than once per transaction");
}

DefaultTransactionStatus defStatus = (DefaultTransactionStatus) status;
//回滚的情况就回滚
if (defStatus.isLocalRollbackOnly()) {
processRollback(defStatus, false);
return;
}
//全局配置回滚??
if (!shouldCommitOnGlobalRollbackOnly() && defStatus.isGlobalRollbackOnly()) {
if (defStatus.isDebug()) {
logger.debug("Global transaction is marked as rollback-only but transactional code requested commit");
}
processRollback(defStatus, true);
return;
}
//提交
processCommit(defStatus);
}
//数据库提交事务,就是一般的数据库的执行操作,就暂时不管了
private void processCommit(DefaultTransactionStatus status) throws TransactionException {
try {
boolean beforeCompletionInvoked = false;

try {
boolean unexpectedRollback = false;
prepareForCommit(status);
triggerBeforeCommit(status);
triggerBeforeCompletion(status);
beforeCompletionInvoked = true;

if (status.hasSavepoint()) {
if (status.isDebug()) {
logger.debug("Releasing transaction savepoint");
}
unexpectedRollback = status.isGlobalRollbackOnly();
status.releaseHeldSavepoint();
}
else if (status.isNewTransaction()) {
if (status.isDebug()) {
logger.debug("Initiating transaction commit");
}
unexpectedRollback = status.isGlobalRollbackOnly();
doCommit(status);
}
else if (isFailEarlyOnGlobalRollbackOnly()) {
unexpectedRollback = status.isGlobalRollbackOnly();
}
if (unexpectedRollback) {
throw new UnexpectedRollbackException(
"Transaction silently rolled back because it has been marked as rollback-only");
}
}
catch (UnexpectedRollbackException ex) {
triggerAfterCompletion(status, TransactionSynchronization.STATUS_ROLLED_BACK);
throw ex;
}
catch (TransactionException ex) {
if (isRollbackOnCommitFailure()) {
doRollbackOnCommitException(status, ex);
}
else {
triggerAfterCompletion(status, TransactionSynchronization.STATUS_UNKNOWN);
}
throw ex;
}
catch (RuntimeException | Error ex) {
if (!beforeCompletionInvoked) {
triggerBeforeCompletion(status);
}
doRollbackOnCommitException(status, ex);
throw ex;
}
try {
triggerAfterCommit(status);
}
finally {
triggerAfterCompletion(status, TransactionSynchronization.STATUS_COMMITTED);
}

}
finally {
cleanupAfterCompletion(status);
}
}
}

5. 总结

  • 通过springboot项目初始化时会根据TransactionAutoConfiguration加载@EnableTransactionManagement,然后通过TransactionManagementConfigurationSelector扫描加载ProxyTransactionManagementConfiguration,进而初始化一个TransactionInterceptorTransactionAttributeSourceBean对象

  • 当有@Transactional注解的bean初始化时在初始化完成时的popularbean()中变成代理的bean

  • TransactionManager是很重要的一个类,关于jdbc的相关操作都放置在内部,且其是一个静态的类,内部通过ThreadLocal维护了当前的访问数据库信息,后续需要用到的地方如mabatis就直接从ThreadLocal中拿到就可以了

6. 注意事项

  • 初始化的TransactionInterceptor中的TransactionManager默认是为空的,也不注入,当连接获取TransactionManager时再懒加载从BeanFactory中获取
  • 由于默认是通过动态代理执行的@Transactional增强,因此方法内部调用是不能开启事务的,若有这方面的需求可以用编程式事务或修改代理方式为aspectj的方式