一、前言
文章目录:Spring源码深度解析:文章目录
由于事务的源码和前篇的Aop源码逻辑很类似,所以本篇中某些内容不会展开去讲解,建议先阅读完 全集目录中的Aop部分,再来阅读本文会更好理解。
上篇中我们讲到@EnableTransactionManagement
引入了两个类:AutoProxyRegistrar
和ProxyTransactionManagementConfiguration
。
AutoProxyRegistrar
: 主要是注册了InfrastructureAdvisorAutoProxyCreator
自动代理创建器。而InfrastructureAdvisorAutoProxyCreator
的逻辑基本上和 Aop 的逻辑相同ProxyTransactionManagementConfiguration
: 注册了事务实现的核心 Bean,包括BeanFactoryTransactionAttributeSourceAdvisor、TransactionAttributeSource、TransactionInterceptor
等。
在上一篇中我们分析了AutoProxyRegistrar
的作用,本篇则来分析一下ProxyTransactionManagementConfiguration
的逻辑过程。
二、 ProxyTransactionManagementConfiguration
ProxyTransactionManagementConfiguration
代码如下,并没有逻辑,就是将几个Bean注入的到容器中。不过这几个bean可都是关键bean,所以我们需要对其中的bean进行分析。
@Configuration
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public class ProxyTransactionManagementConfiguration extends AbstractTransactionManagementConfiguration {
@Bean(name = TransactionManagementConfigUtils.TRANSACTION_ADVISOR_BEAN_NAME)
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public BeanFactoryTransactionAttributeSourceAdvisor transactionAdvisor() {
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() {
TransactionInterceptor interceptor = new TransactionInterceptor();
interceptor.setTransactionAttributeSource(transactionAttributeSource());
if (this.txManager != null) {
interceptor.setTransactionManager(this.txManager);
}
return interceptor;
}
}
BeanFactoryTransactionAttributeSourceAdvisor
: 事务的增强器,该方法是否开始事务,是否需要代理该类都在该类中判断TransactionAttributeSource
: 保存了事务相关的一些信息资源。TransactionInterceptor
: 事务拦截器,事务生成代理类时使用的代理拦截器,编写了事务的规则
1. BeanFactoryTransactionAttributeSourceAdvisor
@SuppressWarnings("serial")
public class BeanFactoryTransactionAttributeSourceAdvisor extends AbstractBeanFactoryPointcutAdvisor {
@Nullable
private TransactionAttributeSource transactionAttributeSource;
private final TransactionAttributeSourcePointcut pointcut = new TransactionAttributeSourcePointcut() {
@Override
@Nullable
protected TransactionAttributeSource getTransactionAttributeSource() {
return transactionAttributeSource;
}
};
/**
* Set the transaction attribute source which is used to find transaction
* attributes. This should usually be identical to the source reference
* set on the transaction interceptor itself.
* @see TransactionInterceptor#setTransactionAttributeSource
*/
public void setTransactionAttributeSource(TransactionAttributeSource transactionAttributeSource) {
this.transactionAttributeSource = transactionAttributeSource;
}
/**
* Set the {@link ClassFilter} to use for this pointcut.
* Default is {@link ClassFilter#TRUE}.
*/
public void setClassFilter(ClassFilter classFilter) {
this.pointcut.setClassFilter(classFilter);
}
@Override
public Pointcut getPointcut() {
return this.pointcut;
}
}
这个根据上面的分析,我们可以知道这个是事务判断的核心,BeanFactoryTransactionAttributeSourceAdvisor
是Advisor
子类,那么我们可以知道其中有两个关键属性:Pointcut
(判断是否可以作用于当前方法) 和 Advice
(作用于当前方法的具体逻辑)。
通过 Aop文章的分析我们可以知道,Advisor
判断一个方法是否匹配,是通过其Pointcut.matchs
属性来判断的。然后我们通过上面的代码,发现其Pointcut
的实现类是TransactionAttributeSourcePointcut
,也就是说,一个方法是否需要使用事务,是通过 TransactionAttributeSourcePointcut#matches
方法判断的。
1.1. TransactionAttributeSourcePointcut
abstract class TransactionAttributeSourcePointcut extends StaticMethodMatcherPointcut implements Serializable {
protected TransactionAttributeSourcePointcut() {
setClassFilter(new TransactionAttributeSourceClassFilter());
}
@Override
public boolean matches(Method method, Class<?> targetClass) {
// 调用 TransactionAttributeSource.getTransactionAttribute方法来匹配
TransactionAttributeSource tas = getTransactionAttributeSource();
return (tas == null || tas.getTransactionAttribute(method, targetClass) != null);
}
... 省略一些无关代码
/**
* Obtain the underlying TransactionAttributeSource (may be {@code null}).
* To be implemented by subclasses.
*/
@Nullable
protected abstract TransactionAttributeSource getTransactionAttributeSource();
/**
* {@link ClassFilter} that delegates to {@link TransactionAttributeSource#isCandidateClass}
* for filtering classes whose methods are not worth searching to begin with.
*/
private class TransactionAttributeSourceClassFilter implements ClassFilter {
@Override
public boolean matches(Class<?> clazz) {
// 如果是一些基础类,则返回false
if (TransactionalProxy.class.isAssignableFrom(clazz) ||
PlatformTransactionManager.class.isAssignableFrom(clazz) ||
PersistenceExceptionTranslator.class.isAssignableFrom(clazz)) {
return false;
}
// 调用 TransactionAttributeSource.isCandidateClass 方法来匹配
TransactionAttributeSource tas = getTransactionAttributeSource();
return (tas == null || tas.isCandidateClass(clazz));
}
}
}
Aop中我们总结了 Pointcut 匹配的需要满足下面两个条件:
pc.getClassFilter().matches(targetClass)
返回truepc.getMethodMatcher().matches(method, targetClass)
返回true
如下图,具体实现在AopUtils#canApply(org.springframework.aop.Pointcut, java.lang.Class<?>, boolean)
中,这里第二点不考虑,因为在这里不会为True
通过TransactionAttributeSourcePointcut
的代码我们可以发现,上面两个条件的关键
可以转换成- 调用
TransactionAttributeSource.isCandidateClass
方法来匹配 :TransactionAttributeSourceClassFilter#matches
中调用了该方法 - 调用
TransactionAttributeSource.getTransactionAttribute
方法来匹配
而TransactionAttributeSource
正是我们在ProxyTransactionManagementConfiguration
中注入的AnnotationTransactionAttributeSource
。
ProxyTransactionManagementConfiguration#transactionAttributeSource()
@Bean
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public TransactionAttributeSource transactionAttributeSource() {
return new AnnotationTransactionAttributeSource();
}
2. AnnotationTransactionAttributeSource
经过上面的分析,我们知道了主要逻辑在isCandidateClass
和getTransactionAttribute
方法中,也就是一个Bean
是否需要事务代理需要通过下面两个方法的校验。因此我们下面来看看这两个方法的实现
2.1 AnnotationTransactionAttributeSource#isCandidateClass
isCandidateClass
主要是判断是否是候选类,即当前的的注解解析器annotationParsers
是否可以解析当前类。annotationParsers
的初始化在其构造函数中,在初始化的过程中中添加了SpringTransactionAnnotationParser
,我们后面的事务注解解析就是通过SpringTransactionAnnotationParser
进行的解析。
这里annotationParsers
有三种解析类型:
SpringTransactionAnnotationParser
:即我们默认的事务解析器,解析的注解是org.springframework.transaction.annotation.Transactional
JtaTransactionAnnotationParser
:解析的注解是javax.transaction.Transactional
Ejb3TransactionAnnotationParser
:解析的注解是javax.ejb.TransactionAttribute
private final Set<TransactionAnnotationParser> annotationParsers;
...
public AnnotationTransactionAttributeSource() {
this(true);
}
...
public AnnotationTransactionAttributeSource(boolean publicMethodsOnly) {
this.publicMethodsOnly = publicMethodsOnly;
// 可以看到,无论什么场景 SpringTransactionAnnotationParser 都是必定存在的解析器
if (jta12Present || ejb3Present) {
this.annotationParsers = new LinkedHashSet<>(4);
this.annotationParsers.add(new SpringTransactionAnnotationParser());
if (jta12Present) {
this.annotationParsers.add(new JtaTransactionAnnotationParser());
}
if (ejb3Present) {
this.annotationParsers.add(new Ejb3TransactionAnnotationParser());
}
}
else {
this.annotationParsers = Collections.singleton(new SpringTransactionAnnotationParser());
}
}
@Override
public boolean isCandidateClass(Class<?> targetClass) {
for (TransactionAnnotationParser parser : this.annotationParsers) {
// 这里是SpringTransactionAnnotationParser 类型, SpringTransactionAnnotationParser#isCandidateClass 中判断了目标类是否存在 org.springframework.transaction.annotation.Transactional 注解
if (parser.isCandidateClass(targetClass)) {
return true;
}
}
return false;
}
在SpringTransactionAnnotationParser#isCandidateClass
中判断了目标类是否存在 org.springframework.transaction.annotation.Transactional
注解,如果存在,这里会返回true,通过校验
2.2 AbstractFallbackTransactionAttributeSource#getTransactionAttribute
getTransactionAttribute
方法的实现在其父类AbstractFallbackTransactionAttributeSource
中实现的
// 获取事务属性,如果
public TransactionAttribute getTransactionAttribute(Method method, @Nullable Class<?> targetClass) {
// 判断声明类是否是 Object
if (method.getDeclaringClass() == Object.class) {
return null;
}
// First, see if we have a cached value.
// 尝试从缓冲中获取
Object cacheKey = getCacheKey(method, targetClass);
TransactionAttribute cached = this.attributeCache.get(cacheKey);
if (cached != null) {
// Value will either be canonical value indicating there is no transaction attribute,
// or an actual transaction attribute.
if (cached == NULL_TRANSACTION_ATTRIBUTE) {
return null;
}
else {
return cached;
}
}
else {
// We need to work it out.
// 没有缓存,则开始解析
TransactionAttribute txAttr = computeTransactionAttribute(method, targetClass);
// Put it in the cache.
// 获取
if (txAttr == null) {
// 放入缓存中
this.attributeCache.put(cacheKey, NULL_TRANSACTION_ATTRIBUTE);
}
else {
// 获取合适的方法名称
String methodIdentification = ClassUtils.getQualifiedMethodName(method, targetClass);
if (txAttr instanceof DefaultTransactionAttribute) {
((DefaultTransactionAttribute) txAttr).setDescriptor(methodIdentification);
}
if (logger.isTraceEnabled()) {
logger.trace("Adding transactional method '" + methodIdentification + "' with attribute: " + txAttr);
}
this.attributeCache.put(cacheKey, txAttr);
}
return txAttr;
}
}
...
// 解析事务注解属性
protected TransactionAttribute computeTransactionAttribute(Method method, @Nullable Class<?> targetClass) {
// Don't allow no-public methods as required.
// 如果只允许解析public 方法 && 当前方法不是 publissh
if (allowPublicMethodsOnly() && !Modifier.isPublic(method.getModifiers())) {
return null;
}
// The method may be on an interface, but we need attributes from the target class.
// If the target class is null, the method will be unchanged.
// method 代表接口中的方法,specificMethod 方法代表实现类中的方法
Method specificMethod = AopUtils.getMostSpecificMethod(method, targetClass);
// First try is the method in the target class.
// 寻找实现类方法的事务属性,即类方法是否有声明事务属性
TransactionAttribute txAttr = findTransactionAttribute(specificMethod);
if (txAttr != null) {
return txAttr;
}
// Second try is the transaction attribute on the target class.
// 在实现类上是否有事务属性的声明
txAttr = findTransactionAttribute(specificMethod.getDeclaringClass());
if (txAttr != null && ClassUtils.isUserLevelMethod(method)) {
return txAttr;
}
// 如果存在接口方法,则从接口方法中尝试去获取事务属性
if (specificMethod != method) {
// Fallback is to look at the original method.
txAttr = findTransactionAttribute(method);
if (txAttr != null) {
return txAttr;
}
// Last fallback is the class of the original method.
txAttr = findTransactionAttribute(method.getDeclaringClass());
if (txAttr != null && ClassUtils.isUserLevelMethod(method)) {
return txAttr;
}
}
// 都没得到则返回没有得到
return null;
}
这里的逻辑还是很清楚的
- 从实现类方法上获取事务注解,若获取到则返回
- 从实现类上获取事务注解,若获取到则返回
- 如果存在接口方法,则从接口方法中获取事务注解,若获取到则返回
- 若仍未获取到,则返回null,认为当前方法没有被注解修饰
2.2.1 AnnotationTransactionAttributeSource#findTransactionAttribute(java.lang.reflect.Method)
在上面的代码中,我们注意到一个方法findTransactionAttribute
。上面代码就是通过 findTransactionAttribute
方法来寻找事务注解属性的。而findTransactionAttribute
的实现在AnnotationTransactionAttributeSource
中。其实现代码如下
protected TransactionAttribute findTransactionAttribute(Method method) {
return determineTransactionAttribute(method);
}
...
protected TransactionAttribute determineTransactionAttribute(AnnotatedElement element) {
for (TransactionAnnotationParser parser : this.annotationParsers) {
TransactionAttribute attr = parser.parseTransactionAnnotation(element);
if (attr != null) {
return attr;
}
}
return null;
}
可以看到AnnotationTransactionAttributeSource
中获取事务注解是通过 TransactionAnnotationParser#parseTransactionAnnotation
方法去解析的,而一开始我们就说过annotationParsers
在构造函数中添加了SpringTransactionAnnotationParser
。我们来看看SpringTransactionAnnotationParser
进行了怎么样的解析。
2.2.2 SpringTransactionAnnotationParser#parseTransactionAnnotation(java.lang.reflect.AnnotatedElement)
到这里,我们终于看到了事务注解的描述,这里就是解析事务注解的各种属性信息了
public TransactionAttribute parseTransactionAnnotation(AnnotatedElement element) {
// 获取事务注解的属性信息
AnnotationAttributes attributes = AnnotatedElementUtils.findMergedAnnotationAttributes(
element, Transactional.class, false, false);
if (attributes != null) {
return parseTransactionAnnotation(attributes);
}
else {
return null;
}
}
....
// 解析事务注解,并返回
protected TransactionAttribute parseTransactionAnnotation(AnnotationAttributes attributes) {
RuleBasedTransactionAttribute rbta = new RuleBasedTransactionAttribute();
// 解析各种属性信息
Propagation propagation = attributes.getEnum("propagation");
rbta.setPropagationBehavior(propagation.value());
Isolation isolation = attributes.getEnum("isolation");
rbta.setIsolationLevel(isolation.value());
rbta.setTimeout(attributes.getNumber("timeout").intValue());
rbta.setReadOnly(attributes.getBoolean("readOnly"));
rbta.setQualifier(attributes.getString("value"));
List<RollbackRuleAttribute> rollbackRules = new ArrayList<>();
for (Class<?> rbRule : attributes.getClassArray("rollbackFor")) {
rollbackRules.add(new RollbackRuleAttribute(rbRule));
}
for (String rbRule : attributes.getStringArray("rollbackForClassName")) {
rollbackRules.add(new RollbackRuleAttribute(rbRule));
}
for (Class<?> rbRule : attributes.getClassArray("noRollbackFor")) {
rollbackRules.add(new NoRollbackRuleAttribute(rbRule));
}
for (String rbRule : attributes.getStringArray("noRollbackForClassName")) {
rollbackRules.add(new NoRollbackRuleAttribute(rbRule));
}
rbta.setRollbackRules(rollbackRules);
return rbta;
}
我们的分析到这里,就已经可以知道了Spring 中对事务注解的解析过程,逻辑基本和 Spring Aop 类似。
@EnableTransactionManagement
通过引入TransactionManagementConfigurationSelector
注册了AutoProxyRegistrar
和ProxyTransactionManagementConfiguration
两个类。AutoProxyRegistrar
中注册了InfrastructureAdvisorAutoProxyCreator
自动代理创建器InfrastructureAdvisorAutoProxyCreator
中拦截bean的创建过程,通过BeanFactoryTransactionAttributeSourceAdvisor
来判断bean中是否有事务注解,有则进行代理。
在上面的逻辑中,我们似乎没有发现Spring事务代理的具体过程,实际上代理的过程是在 TransactionInterceptor
中。
3. TransactionInterceptor
在 Aop 的分析文章中,我们知道了无论是 Jdk代理还是 Cglib代理,其增强实现都是调用Advisor
中的Advice
实现。BeanFactoryTransactionAttributeSourceAdvisor
作为Advisor
的实现类,自然要遵从Advisor
的处理方式,当代理被调用时会调用这个类的增强方法,也就是此bean 的Advice
,而在解析事务标签是,我们把TransactionInterceptor
注入到了 BeanFactoryTransactionAttributeSourceAdvisor
中,所以调用事务增强器增强代理类的时会首先执行TransactionInterceptor
进行增强,同时也就是TransactionInterceptor#invoke
完成了整个事务的逻辑。
所以我们这里自然要看TransactionInterceptor#invoke
方法。
public Object invoke(MethodInvocation invocation) throws Throwable {
Class<?> targetClass = (invocation.getThis() != null ? AopUtils.getTargetClass(invocation.getThis()) : null);
// 在事务修饰下执行方法
return invokeWithinTransaction(invocation.getMethod(), targetClass, invocation::proceed);
}
可以看到核心逻辑都在invokeWithinTransaction
方法中,这里调用的 invokeWithinTransaction
方法 实际是 TransactionAspectSupport#invokeWithinTransaction
方法。所以下面我们来看看 TransactionAspectSupport#invokeWithinTransaction
方法的具体实现
3.1. TransactionAspectSupport#invokeWithinTransaction
@Nullable
protected Object invokeWithinTransaction(Method method, @Nullable Class<?> targetClass,
final InvocationCallback invocation) throws Throwable {
// If the transaction attribute is null, the method is non-transactional.
// 获取事务数据源,这里获取的数据源就是在 TransactionInterceptor 注入的时候的设置的属性transactionAttributeSource = AnnotationTransactionAttributeSource。
// 在 ProxyTransactionManagementConfiguration 中完成
TransactionAttributeSource tas = getTransactionAttributeSource();
// 1. 获取对应的事务属性
final TransactionAttribute txAttr = (tas != null ? tas.getTransactionAttribute(method, targetClass) : null);
// 2. 获取一个合适的 TransactionManager
final TransactionManager tm = determineTransactionManager(txAttr);
// 3. 对于反应式事务的处理
// 从Spring Framework 5.2 M2开始,Spring通过ReactiveTransactionManagerSPI 支持响应式/反应式事务管理
if (this.reactiveAdapterRegistry != null && tm instanceof ReactiveTransactionManager) {
ReactiveTransactionSupport txSupport = this.transactionSupportCache.computeIfAbsent(method, key -> {
if (KotlinDetector.isKotlinType(method.getDeclaringClass()) && KotlinDelegate.isSuspend(method)) {
throw new TransactionUsageException(
"Unsupported annotated transaction on suspending function detected: " + method +
". Use TransactionalOperator.transactional extensions instead.");
}
ReactiveAdapter adapter = this.reactiveAdapterRegistry.getAdapter(method.getReturnType());
if (adapter == null) {
throw new IllegalStateException("Cannot apply reactive transaction to non-reactive return type: " +
method.getReturnType());
}
return new ReactiveTransactionSupport(adapter);
});
return txSupport.invokeWithinTransaction(
method, targetClass, invocation, txAttr, (ReactiveTransactionManager) tm);
}
// 判断 tm是否是 PlatformTransactionManager 类型,是则强转,不是则抛出异常
PlatformTransactionManager ptm = asPlatformTransactionManager(tm);
// 构造方法的唯一标识( 全路径了类名.方法)
final String joinpointIdentification = methodIdentification(method, targetClass, txAttr);
// 4. 对不同事务情景的处理
// 声明式事务的处理
// 如果txAttr为空或者tm 属于非CallbackPreferringPlatformTransactionManager,执行目标增强
// 在TransactionManager上,CallbackPreferringPlatformTransactionManager实现PlatformTransactionManager接口,暴露出一个方法用于执行事务处理中的回调
if (txAttr == null || !(ptm instanceof CallbackPreferringPlatformTransactionManager)) {
// Standard transaction demarcation with getTransaction and commit/rollback calls.
// 5.如果有必要,创建事务信息。主要由于事务的传播属性,所以这里并不一定会创建事务
TransactionInfo txInfo = createTransactionIfNecessary(ptm, txAttr, joinpointIdentification);
Object retVal;
try {
// This is an around advice: Invoke the next interceptor in the chain.
// This will normally result in a target object being invoked.
// 6. 执行被增强的方法
retVal = invocation.proceedWithInvocation();
}
catch (Throwable ex) {
// target invocation exception
// 7. 异常回滚
completeTransactionAfterThrowing(txInfo, ex);
throw ex;
}
finally {
// 8. 提交之前清除事务信息
cleanupTransactionInfo(txInfo);
}
if (vavrPresent && VavrDelegate.isVavrTry(retVal)) {
// Set rollback-only in case of Vavr failure matching our rollback rules...
TransactionStatus status = txInfo.getTransactionStatus();
if (status != null && txAttr != null) {
retVal = VavrDelegate.evaluateTryFailure(retVal, txAttr, status);
}
}
// 9.提交事务
commitTransactionAfterReturning(txInfo);
return retVal;
}
// 编程式事务(CallbackPreferringPlatformTransactionManager)的处理。这里的逻辑基本都被封装了
else {
final ThrowableHolder throwableHolder = new ThrowableHolder();
try {
// 直接调用execute 方法。由于事务的提交回滚等操作都已经封装好了,所以这里并没有对事务进行详细的操作。
Object result = ((CallbackPreferringPlatformTransactionManager) ptm).execute(txAttr, status -> {
// 准备事务信息
TransactionInfo txInfo = prepareTransactionInfo(ptm, txAttr, joinpointIdentification, status);
try {
// 执行方法
Object retVal = invocation.proceedWithInvocation();
if (vavrPresent && VavrDelegate.isVavrTry(retVal)) {
// Set rollback-only in case of Vavr failure matching our rollback rules...
retVal = VavrDelegate.evaluateTryFailure(retVal, txAttr, status);
}
return retVal;
}
catch (Throwable ex) {
if (txAttr.rollbackOn(ex)) {
// A RuntimeException: will lead to a rollback.
if (ex instanceof RuntimeException) {
throw (RuntimeException) ex;
}
else {
throw new ThrowableHolderException(ex);
}
}
else {
// A normal return value: will lead to a commit.
throwableHolder.throwable = ex;
return null;
}
}
finally {
// 清除事务信息
cleanupTransactionInfo(txInfo);
}
});
// Check result state: It might indicate a Throwable to rethrow.
if (throwableHolder.throwable != null) {
throw throwableHolder.throwable;
}
return result;
}
catch (ThrowableHolderException ex) {
throw ex.getCause();
}
catch (TransactionSystemException ex2) {
if (throwableHolder.throwable != null) {
logger.error("Application exception overridden by commit exception", throwableHolder.throwable);
ex2.initApplicationException(throwableHolder.throwable);
}
throw ex2;
}
catch (Throwable ex2) {
if (throwableHolder.throwable != null) {
logger.error("Application exception overridden by commit exception", throwableHolder.throwable);
}
throw ex2;
}
}
}
从上面的代码中,我们可以知道Spring支持声明式事务和编程式事务两种处理。两者的实现本质基本相同。在invoke
方法中我们也可以看到这两种方式的实现,通常我们使用的都是通过 @Transactional
注解修饰的声明式事务,所以我们下面主要分析 声明式事务 的处理过程。
- 获取事务属性
TransactionAttribute
,TransactionAttribute
中包含 传播属性,timeout
等事务属性信息。如果是使用@Transactional
注解,这个解析过程是在AnnotationTransactionAttributeSource#findTransactionAttribute(java.lang.reflect.Method)
中完成,具体看 篇2中有解释。 - 加载配置中的
TrancationManager
, 事务管理器,是事务实现的基础,我们这里获取到的是DataSourceTransactionManager
。 - 对反应式事务的处理。
- 不同事务处理方式使用不同的逻辑。在上面的代码中主要是两种情况,一是声明式事务,这种情况是通过
@Transactional
注解修饰方法来表示开启事务。另一种情况是编程式事务,即可以通过xml
方式或者配置类方式来进行完成事务功能,其实TransactionTemplate
的实现就是编程式事务,但通过TransactionTemplate
并不会走到这个逻辑,这里的编程式事务应该单独是通过xml或者配置类方式来配置的。
对于声明式事务的处理和编程式事务的处理,区别主要在两点。一是事务属性上,因为编程式事务是不需要事务属性的,二是TransactionManager
的不同,CallbackPreferringPlatformTransactionManager
实现了PlatformTransactionManager
接口,暴露了一个方法用于执行事务处理中的回调。所以这两种方式都可以作为事务处理方式的判断。 - 在目标方法执行前获取事务并收集事务信息。
事务信息与事务属性并不相同,也就是TransactionInfo
和TransactionAttribute
并不相同,TransactionInfo
中包含TransactionAttribute
信息,并且处理TransactionAttribute
之外还有其他事物信息,比如PlatformTransactionManager
以及TransactionStatus
相关信息。 - 执行目标方法
- 如果出现异常,则进行回滚。这里需要注意,默认的情况下只有
RuntimeException
异常才会执行回滚。可以通过@Transactional(rollbackFor = Exception.class)
的方式来指定触发回滚的异常 - 提交事务前的事务信息清除
- 提交事务
- 若是 编程式事务,则直接执行execute方法即可,这里就不再讲解。
注:PlatformTransactionManager
和ReactiveTransactionManager
二者都是为了实现事务,PlatformTransactionManager
在内部进行事务执行流程的封装,并且暴露出来一个execute
方法用于执行事务的具体信息,TransactionTemplate
的声明式事务就是基于此实现的。而ReactiveTransactionManager
则是比较原始的,需要我们自己来实现事务的整个逻辑。
上面比较笼统的讲了事务的实现,下面们主要分析以下三个方法,也是事务的的关键流程:
- 事务的创建 -
createTransactionIfNecessary
- 事务的回滚 -
completeTransactionAfterThrowing
- 事务的提交 -
commitTransactionAfterReturning
以上:内容部分参考
《Spring源码深度解析》
如有侵扰,联系删除。 内容仅用于自我记录学习使用。如有错误,欢迎指正