欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 财经 > 创投人物 > Spring声明式事务源码分析

Spring声明式事务源码分析

2024/10/24 4:32:04 来源:https://blog.csdn.net/weixin_42612223/article/details/140523503  浏览:    关键词:Spring声明式事务源码分析

文章目录

    • 概要
    • @EnableTransactionManagement
    • AutoProxyRegistrar
    • ProxyTransactionManagementConfiguration
    • TransactionInterceptor 事务拦截器

概要

编程式事务:在业务代码中添加事务控制代码,这样的事务控制机制就叫做编程式事务
声明式事务:通过xml或者注解配置的⽅式达到事务控制的⽬的,叫做声明式事务

Spring的事务管理的核心接口是org.springframework.transaction.PlatformTransactionManager

public interface PlatformTransactionManager {//  获取事务状态信息//	AbstractPlatformTransactionManager抽象类中TransactionStatus getTransaction(@Nullable TransactionDefinition definition) throws TransactionException;//  提交事务//	进入 AbstractPlatformTransactionManager.commitvoid commit(TransactionStatus status) throws TransactionException;//  回滚事务//	AbstractPlatformTransactionManager.rollback()void rollback(TransactionStatus status) throws TransactionException;}

此接⼝是Spring的事务管理器核⼼接⼝。Spring本身并不⽀持事务实现,只是负责提供标准,应⽤底层⽀持什么样的事务,需要提供具体实现类。此处也是策略模式的具体应⽤。在Spring框架中,也为我们内置了⼀些具体策略:DataSourceTransactionManager ,HibernateTransactionManager

DataSourceTransactionManager 归根结底是横切逻辑代码,声明式事务要做的就是使⽤Aop(动态代理)来将事务控制逻辑织⼊到业务代码.

声明式事务纯注解方式使用如下:
在 Spring 的配置类上添加 @EnableTransactionManagement 注解即可

@Configuration@EnableTransactionManagementpublic class AppConfig {
}

那么,该注解@EnableTransactionManagement具体做了哪些东西呢?

@EnableTransactionManagement

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(TransactionManagementConfigurationSelector.class)
public @interface EnableTransactionManagement {boolean proxyTargetClass() default false;AdviceMode mode() default AdviceMode.PROXY;int order() default Ordered.LOWEST_PRECEDENCE;}

@EnableTransactionManagement 注解使⽤ @Import 标签引⼊了TransactionManagementConfigurationSelector类,这个类⼜向容器中导⼊了两个重要的组件.

在这里插入图片描述

AutoProxyRegistrar

AutoProxyRegistrar 类的 registerBeanDefinitions ⽅法中⼜注册了⼀个组件
在这里插入图片描述
进⼊ AopConfigUtils.registerAutoProxyCreatorIfNecessary ⽅法

在这里插入图片描述
发现最终,注册了⼀个叫做 InfrastructureAdvisorAutoProxyCreator 的 Bean,⽽这个类是
AbstractAutoProxyCreator 的⼦类,实现了 SmartInstantiationAwareBeanPostProcessor 接⼝

public class InfrastructureAdvisorAutoProxyCreator extends
AbstractAdvisorAutoProxyCreator
public abstract class AbstractAdvisorAutoProxyCreator extends
AbstractAutoProxyCreator
public abstract class AbstractAutoProxyCreator extends
ProxyProcessorSupportimplements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware

在这里插入图片描述
它实现了SmartInstantiationAwareBeanPostProcessor,说明这是⼀个后置处理器,⽽且跟spring AOP 开启@EnableAspectJAutoProxy 时注册的 AnnotationAwareAspectJProxyCreator实现的是同⼀个接⼝,所以说,声明式事务是 springAOP 思想的⼀种应⽤

ProxyTransactionManagementConfiguration

@Configuration
public class ProxyTransactionManagementConfiguration extends AbstractTransactionManagementConfiguration {@Bean(name = TransactionManagementConfigUtils.TRANSACTION_ADVISOR_BEAN_NAME)@Role(BeanDefinition.ROLE_INFRASTRUCTURE)public BeanFactoryTransactionAttributeSourceAdvisor transactionAdvisor() {// 事务增强器BeanFactoryTransactionAttributeSourceAdvisor advisor = new BeanFactoryTransactionAttributeSourceAdvisor();// 向事务增强器中注⼊ 属性解析器 transactionAttributeSourceadvisor.setTransactionAttributeSource(transactionAttributeSource());// 向事务增强器中注⼊ 事务拦截器 transactionInterceptoradvisor.setAdvice(transactionInterceptor());if (this.enableTx != null) {advisor.setOrder(this.enableTx.<Integer>getNumber("order"));}return advisor;}@Bean@Role(BeanDefinition.ROLE_INFRASTRUCTURE)// 属性解析器 transactionAttributeSourcepublic TransactionAttributeSource transactionAttributeSource() {return new AnnotationTransactionAttributeSource();}@Bean@Role(BeanDefinition.ROLE_INFRASTRUCTURE)// 事务拦截器 transactionInterceptorpublic TransactionInterceptor transactionInterceptor() {TransactionInterceptor interceptor = new TransactionInterceptor();interceptor.setTransactionAttributeSource(transactionAttributeSource());if (this.txManager != null) {interceptor.setTransactionManager(this.txManager);}return interceptor;}}

ProxyTransactionManagementConfiguration是⼀个容器配置类,注册了⼀个组件transactionAdvisor,称为事务增强器,然后在这个事务增强器中⼜注⼊了两个属性:transactionAttributeSource,即属性解析器transactionAttributeSource 和 事务拦截器transactionInterceptor

属性解析器 AnnotationTransactionAttributeSource 部分源码如下:

public class AnnotationTransactionAttributeSource extends AbstractFallbackTransactionAttributeSourceimplements Serializable {private static final boolean jta12Present = ClassUtils.isPresent("javax.transaction.Transactional", AnnotationTransactionAttributeSource.class.getClassLoader());private static final boolean ejb3Present = ClassUtils.isPresent("javax.ejb.TransactionAttribute", AnnotationTransactionAttributeSource.class.getClassLoader());private final boolean publicMethodsOnly;// 注解解析器集合private final Set<TransactionAnnotationParser> annotationParsers;

属性解析器有⼀个成员变量是annotationParsers,是⼀个集合,可以添加多种注解解析器(TransactionAnnotationParser),我们关注 Spring 的注解解析器,部分源码如下

在这里插入图片描述
在这里插入图片描述
属性解析器的作⽤之⼀就是⽤来解析@Transaction注解

TransactionInterceptor 事务拦截器

在这里插入图片描述
在这里插入图片描述
上述组件如何关联起来的?

  • 事务拦截器实现了MethodInterceptor接⼝,追溯⼀下上⾯提到的InfrastructureAdvisorAutoProxyCreator后置处理器,它会在代理对象执⾏⽬标⽅法的时候获取其拦截器链,⽽拦截器链就是这个TransactionInterceptor,这就把这两个组件联系起来;
    构造⽅法传⼊PlatformTransactionManager(事务管理器)、TransactionAttributeSource(属性解析器),但是追溯⼀下上⾯贴的ProxyTransactionManagementConfiguration的源码,
    在注册事务拦截器的时候并没有调⽤这个带参构造⽅法,⽽是调⽤的⽆参构造⽅法,然后再调⽤set⽅法注⼊这两个属性,效果⼀样。

invokeWithinTransaction ⽅法源码如下:

	//模板方法目标//1、获取事务属性//2、创建事务//3、调用目标方法//4、回滚 事务 or  提交事务@Nullableprotected Object invokeWithinTransaction(Method method, @Nullable Class<?> targetClass,final InvocationCallback invocation) throws Throwable {// 获取事务属性,如果事务属性为空,则没有事务TransactionAttributeSource tas = getTransactionAttributeSource();//继承TransactionDefinition,返回默认的传播、隔离级别final TransactionAttribute txAttr = (tas != null ? tas.getTransactionAttribute(method, targetClass) : null);// 获取DataSourceTransactionManager 用于管理 JDBC 的 Connection。final PlatformTransactionManager tm = determineTransactionManager(txAttr);// 切点标识-->com.tx.test.impl.UserServiceImpl.insertfinal String joinpointIdentification = methodIdentification(method, targetClass, txAttr);//txAttr(传播属性&隔离级别)if (txAttr == null || !(tm instanceof CallbackPreferringPlatformTransactionManager)) {// TODO: 创建(开启)事务(根据事务的传播行为属性去判断是否创建一个事务)TransactionInfo txInfo = createTransactionIfNecessary(tm, txAttr, joinpointIdentification);Object retVal = null;try {// TODO: 调用目标方法  org.springframework.aop.framework.ReflectiveMethodInvocation.proceedretVal = invocation.proceedWithInvocation();} catch (Throwable ex) {// TODO: 回滚事务  目标方法调用发生了异常(后置增强),completeTransactionAfterThrowing(txInfo, ex);throw ex;} finally {// 执行成功  清理信息cleanupTransactionInfo(txInfo);}//TODO: 提交事务commitTransactionAfterReturning(txInfo);return retVal;} else {final ThrowableHolder throwableHolder = new ThrowableHolder();// It's a CallbackPreferringPlatformTransactionManager: pass a TransactionCallback in.try {Object result = ((CallbackPreferringPlatformTransactionManager) tm).execute(txAttr, status -> {TransactionInfo txInfo = prepareTransactionInfo(tm, txAttr, joinpointIdentification, status);try {return invocation.proceedWithInvocation();} catch (Throwable ex) {...} 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) {。。。}}}

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com