iis服务器助手广告
返回顶部
首页 > 资讯 > 后端开发 > Python >spring声明式事务@Transactional底层工作原理
  • 474
分享到

spring声明式事务@Transactional底层工作原理

2024-04-02 19:04:59 474人浏览 八月长安

Python 官方文档:入门教程 => 点击学习

摘要

目录引言工作机制简述事务aop核心类释义@TransactionalTransactionAttributespringTransactionAnnotationParserAnno

引言

写这篇博文有个来由,是为了解决博主遇到的多数据源的事务问题(用不了JTA),所以深入到spring-tx的源码学习了一番,非常有收获,最后博主的分布式事务问题也迎刃而解了,这个文章算个开篇,关于如何处理多数据源事务,待下文分解。本文涉及到的技术包含spring aop的使用、spring bean生命周期等,如果能够真正理解Transactional的工作原理,对排查事务相关的问题有非常大的帮助。

spring-tx版本:5.0.2

工作机制简述

先来看一张官方的事务简图:

spring定义了@Transactional注解,基于AbstractBeanFactoryPointcutAdvisor、StaticMethodMatcherPointcut、MethodInterceptor的aop编程模式,增强了添加@Transactional注解的方法。同时抽象了事务行为为PlatformTransactionManager(事务管理器)、TransactionStatus(事务状态)、TransactionDefinition(事务定义)等形态。最终将事务的开启、提交、回滚等逻辑嵌入到被增强的方法的前后,完成统一的事务模型管理。

事务AOP核心类释义

@Transactional

事务注解,用于定位aop的切入点,事务注解里包含了完整事务的所有基本属性,常见的属性如:

transactionManager:事务管理器

propagation:传播行为定义,枚举类型,是spring独有的事务行为设计,默认为PROPAGATION_REQUIRED(支持当前事务,不存在则新建)

isolation:隔离级别,对应数据库的隔离级别实现,Mysql默认的隔离级别是 read-committed

timeout:超时时间,默认使用数据库的超时,mysql默认的事务等待超时为5分钟

readOnly:是否只读,默认是false

rollbackFor:异常回滚列表,默认的是RuntimeException异常回滚

TransactionAttribute

事务属性抽象接口类,承载了@Transactional注解里的所有属性,实现类的继承关系如下类结构图,这个实例在被注解解析器创建好后,会在事务上下文中传递

SpringTransactionAnnotationParser

见名知意,这个类是spring的事务注解解析器,实现自TransactionAnnotationParser接口,是spring管理的事务解析器,用于解析@Transactional注解,将注解里的属性设置到TransactionAttribute的实现类属性里。除了这个,另还有两个实现,分别是JTA事务注解解析器,和EJB事务注解管理解析器,区别是解析的注解不同,spring是@Transactional,jta是javax.transaction.Transactional,EJB是javax.ejb.TransactionAttribute。这个地方应用和apache dubbo2.7.x版本解析dubbo的@service注解是一样一样的。关键代码如下,通过AnnotatedElementUtils类,这个类在spring-core包下,找到注解属性集AnnotationAttributes,如果不为空,则包装成事务属性集返回

@Override
	@Nullable
	public TransactionAttribute parseTransactionAnnotation(AnnotatedElement element) {
		AnnotationAttributes attributes = AnnotatedElementUtils.findMergedAnnotationAttributes(
				element, Transactional.class, false, false);
		if (attributes != null) {
			return parseTransactionAnnotation(attributes);
		}
		else {
			return null;
		}
	}

AnnotationTransactionAttributeSource

见名知意,这个类是注解事务属性集的源,怎么理解呢?spring抽象了获取事务属性集的行为,而AnnotationTransactionAttributeSource正是@Transactional注解方式的事务属性集收集实现。SpringTransactionAnnotationParser就是作用于这个里面,用于发现@Transactiona注解的方法

TransactionAttributeSourcePointcut

也是见名知意,Pointcut属于aop的概念范畴,需要了解spring aop的知识才能看明白,这个就是@Transactional注解的切点,AnnotationTransactionAttributeSource作用于此,用于寻找@Transactiona注解的方法,关键代码如下:

public boolean matches(Method method, Class targetClass) {
		TransactionAttributeSource tas = getTransactionAttributeSource();
		return (tas == null || tas.getTransactionAttribute(method, targetClass) != null);
	}

TransactionInterceptor

事务的拦截器。aop编程里,有了切入点Pointcut,就要有通知advice,我们熟悉的spring aop里有前置、后置、环绕、异常等通知类型,TransactionInterceptor属于自定义通知模型实现,实现自Advice接口,类似于环绕通知,具体见类结构图,如下:

核心方法如下:

public Object invoke(MethodInvocation invocation) throws Throwable {
		// Work out the target class: may be {@code null}.
		// The TransactionAttributeSource should be passed the target class
		// as well as the method, which may be from an interface.
		Class targetClass = (invocation.getThis() != null ? AopUtils.getTargetClass(invocation.getThis()) : null);
		// Adapt to TransactionAspectSupport's invokeWithinTransaction...
		return invokeWithinTransaction(invocation.getMethod(), targetClass, invocation::proceed);
	}

被@Transactional注解的方法,如果被aop正确的增强了,运行的时候都会进入到这个方法里面,如果你发现事务不生效啊等等问题,可以从这里开始定位真实原因

BeanFactoryTransactionAttributeSourceAdvisor

事务增强器,用于增强添加了@Transactional注解的方法,上面提到的这些核心类,最终都作用于这里,用于寻找@Transactional注解的方法和织入事务处理逻辑

ProxyTransactionManagementConfiguration

代理事务管理的配置类,上面介绍的这些事务aop编程相关的在这个里面组合配置生效的,同时,如果你有特殊的个性化的需求,也可以自定义注册这个里面的实例。比如我嫌弃@Transactional注解太长了,想用@Tx注解。没关系,直接定义个TransactionAttributeSource实现,解析@Tx的方法,然后注册到spring的上线文中即可。代码如:

@Configuration(proxyBeanMethods = false)
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.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;
	}
}

事务抽象核心类释义

PlatformTransactionManager

平台事务管理器,这是Spring事务基础设施中的中心接口。它定义了三个最最基本的事务方法,getTransaction获取事务,包含了事务开启的行为,commit提交事务,rollback回滚事务。代码如下:

public interface PlatformTransactionManager extends TransactionManager {
	TransactionStatus getTransaction(@Nullable TransactionDefinition definition)
			throws TransactionException;
	void commit(TransactionStatus status) throws TransactionException;
	void rollback(TransactionStatus status) throws TransactionException;
}

在spring-tx中并没有提供真正的实现类,只提供了一个抽象派生类AbstractPlatformTransactionManager,并建议其他实现基于这个派生类,因为它预先实现了定义的传播行为并处理事务同步处理。子类必须为底层事务的特定状态实现模板方法,例如:begin、suspend、resume、commit等。我们平时常见的实现有:JpaTransactionManager、JtaTransactionManager、DataSourceTransactionManager等。事务管理器和事务aop处理的逻辑本身没有任何耦合,只需将PlatformTransactionManager实例注册到spring上下文中即可,事务拦截器会通过获取到@Transactional里的transactionManager属性去上下文中寻找事务管理器,并将其缓存起来,见TransactionAspectSupport.java里的determineTransactionManager方法

protected PlatformTransactionManager determineTransactionManager(@Nullable TransactionAttribute txAttr) {
		// Do not attempt to lookup tx manager if no tx attributes are set
		if (txAttr == null || this.beanFactory == null) {
			return asPlatformTransactionManager(getTransactionManager());
		}
		String qualifier = txAttr.getQualifier();
		if (StringUtils.hasText(qualifier)) {
			return determineQualifiedTransactionManager(this.beanFactory, qualifier);
		}
		else if (StringUtils.hasText(this.transactionManagerBeanName)) {
			return determineQualifiedTransactionManager(this.beanFactory, this.transactionManagerBeanName);
		}
		else {
			PlatformTransactionManager defaultTransactionManager = asPlatformTransactionManager(getTransactionManager());
			if (defaultTransactionManager == null) {
				defaultTransactionManager = asPlatformTransactionManager(
						this.transactionManagerCache.get(DEFAULT_TRANSACTION_MANAGER_KEY));
				if (defaultTransactionManager == null) {
					defaultTransactionManager = this.beanFactory.getBean(PlatformTransactionManager.class);
					this.transactionManagerCache.putIfAbsent(
							DEFAULT_TRANSACTION_MANAGER_KEY, defaultTransactionManager);
				}
			}
			return defaultTransactionManager;
		}
	}

TransactionStatus

事务状态抽象,用这个类的实现来维护当前的事务状态,spring-tx里提供了默认的实现DefaultTransactionStatus。一般情况下这个不需要我们关心,它和PlatformTransactionManager是成对存在的,心细的你可能已经发现了,PlatformTransactionManager里的三个事务行为传递的就是TransactionStatus。我们知道事务aop增强了添加@Transactional的方法,在执行方法前调用PlatformTransactionManager.getTransaction开启事务,之后调用commit方法提交事务,提交事务的入参TransactionStatus就是开启事务获得的。参见TransactionAspectSupport.java里的createTransactionIfNecessary方法

TransactionDefinition

事务定义,对应了TransactionAttribute,最终通过aop得到的TransactionAttribute里的属性会被传递到TransactionDefinition里,所以TransactionDefinition里也包含了所有事务相关的属性,PlatformTransactionManager.getTransaction正是通过这个里面的属性去获取的事务。AbstractPlatformTransactionManager派生类里也是通过这个里面的属性去判断协调spring的事务传播行为的

结语

当梳理完spring-tx模块的整个结构和工作方式后,仿佛拉开了spring事务管理的面纱,很多事务的执行细节一览无余。很多事务相关的问题也就很容易解释了。比如常见的类中的方法直接调用方法事务不生效等问题,以及可以非常清晰的理解spring的传播行为的真正含义等。最后预告下,spring对于多数据源的事务处理解决方案ChainedTransactionManager

以上就是spring声明式事务@Transactional底层工作原理的详细内容,更多关于spring声明式事务@Transactional工作原理的资料请关注编程网其它相关文章!

--结束END--

本文标题: spring声明式事务@Transactional底层工作原理

本文链接: http://www.lsjlt.com/news/140297.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • spring声明式事务@Transactional底层工作原理
    目录引言工作机制简述事务AOP核心类释义@TransactionalTransactionAttributeSpringTransactionAnnotationParserAnno...
    99+
    2024-04-02
  • Spring底层事务原理解析
    目录一、@EnableTransactionManagement工作原理二、Spring事务基本执行原理四、Spring事务传播机制五、Spring事务传播机制分类六、Spring事...
    99+
    2022-12-10
    Spring底层事务原理 Spring底层事务 Spring底层原理
  • Spring @Transactional工作原理详解
    本文将深入研究Spring的事务管理。主要介绍@Transactional在底层是如何工作的。之后的文章将介绍:propagation(事务传播)和isolation(隔离性)等属性的使用事务使用的陷阱有哪些以及如何避免JPA和事务管理很重...
    99+
    2023-05-30
  • Spring中的@Transactional的工作原理
    目录1、原理2、用法3、拓展1、原理 事务的概念想必大家都很清楚,其ACID特性在开发过程中占有重要的地位。同时在并发过程中会出现一些一致性问题,为了解决一致性问题,也出现了四种隔离...
    99+
    2024-04-02
  • Spring 事务(编程式事务、声明式事务@Transactional、事务隔离级别、事务传播机制)
    文章目录 1. 事务的定义2. Spring 中事务的实现2.1 MySQL 中使用事务2.2 Spring 中编程式事务的实现2.3 Spring 中声明式事务2.3.1 声明式事务的实现 ...
    99+
    2023-10-02
    spring mysql java 事务 事务传播机制
  • Spring AOP底层原理及代理模式
    目录Spring AOP底层原理代理模式一、什么是 AOP二、AOP 底层原理1. 什么是代理?2. 什么是静态代理3. 什么是动态代理Spring AOP底层原理代理模式 一、什么...
    99+
    2024-04-02
  • Java Spring 声明式事务详解
    目录项目结构: 表结构: 基于xml的声明式事务配置完全注解(零xml)方式配置事务参数no-rollback-forrollback-forread-onlytimeoutisol...
    99+
    2024-04-02
  • PHP底层工作原理是什么
    这篇文章将为大家详细讲解有关PHP底层工作原理是什么,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。PHP底层工作原理图1 php结构从图上可以看出,php从下到上是一个4层体系①Zend引擎Zend整体用...
    99+
    2023-06-17
  • Spring深入刨析声明式事务
    目录声明式事务回顾事务测试Spring中的事务管理声明式事务 回顾事务 事务在项目开发过程非常重要,涉及到数据的一致性的问题,不容马虎!事务管理是企业级应用程序开发中必备技术,用来确...
    99+
    2022-12-08
    Spring声明式事务 Java声明式事务
  • 如何解决spring声明式事务@Transactional不回滚的多种情况问题
    这篇文章给大家分享的是有关如何解决spring声明式事务@Transactional不回滚的多种情况问题的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。一、 spring 事务原理一、Spring事务原理在使用JD...
    99+
    2023-06-25
  • spring声明式事务 @Transactional 不回滚的多种情况以及解决方案
    目录一、 spring 事务原理问题一、@Transactional 应该加到什么地方,如果加到Controller会回滚吗?问题二、 @Transactional 注解中用不用加r...
    99+
    2024-04-02
  • 如何在Spring中使用声明式事务管理
    本篇文章为大家展示了如何在Spring中使用声明式事务管理,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。基于TransactionProxyFactoryBean的事务管理配置Spring中配置AO...
    99+
    2023-05-31
    spring 声明式事务管理
  • spring事务及声明式事务的使用方法
    这篇文章主要介绍spring事务及声明式事务的使用方法,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!本篇文章给大家带来的内容是关于如何理解spring事务及声明式事务的使用,包括数据...
    99+
    2024-04-02
  • Spring声明式事务配置使用详解
    目录序章准备工作创建jdbc.properties配置Spring的配置文件声明式事务概念代码讲解配置 Spring 的配置文件创建表创建组件测试无事务情况加入事务序章 Spring...
    99+
    2024-04-02
  • Spring声明式事务注解之@EnableTransactionManagement解析
    Spring声明式事务注解之@EnableTransactionManagement 1. 说明 @EnableTransactionManagement声明在主配置类上,表示开启声...
    99+
    2024-04-02
  • spring是如何实现声明式事务的
    前言 今天我们来讲讲spring的声明式事务。 开始 说到声明式事务,我们现在回顾一下事务这个概念,什么是事务呢,事务指的是逻辑上的⼀组操作,组成这组操作的各个单...
    99+
    2024-04-02
  • spring注解如何开启声明式事务
    目录spring开启声明式事务导入依赖配置类文件业务逻辑编写测试代码总结spring开启声明式事务 导入依赖 pom.xml <dependencies>        ...
    99+
    2022-12-28
    spring 注解 注解开启声明式事务 spring声明式事务
  • PHP 底层的运行机制和工作原理
    阅读目录 阐述一、PHP的设计理念及特点PHP 为什么没有多线程?1、PHP 与多线程2、PHP是单线程,多进程模型3、 php为什么选择多进程,而不是多线程4、场景 二、PHP 四...
    99+
    2023-08-31
    php 服务器 开发语言
  • Spring AOP底层原理及代理模式实例分析
    这篇文章主要介绍“Spring AOP底层原理及代理模式实例分析”,在日常操作中,相信很多人在Spring AOP底层原理及代理模式实例分析问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”S...
    99+
    2023-06-30
  • Spring声明式事务注解的源码分析
    本文小编为大家详细介绍“Spring声明式事务注解的源码分析”,内容详细,步骤清晰,细节处理妥当,希望这篇“Spring声明式事务注解的源码分析”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。1、@EnableTr...
    99+
    2023-07-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作