springBoot 事务基本原理
创始人
2024-05-29 10:26:01
0

springBoot事务基本原理是基于spring的BeanPostProcessor,在springBoot中事务使用方式为:

一、在启动类上添加注解:@EnableTransactionManagement

二、在需要事务的接口上添加注解:@Transactional

基本原理:

注解:@EnableTransactionManagement  存在一个import  :

@Import(TransactionManagementConfigurationSelector.class)

TransactionManagementConfigurationSelector 继承树为:

 由此可以看到,TransactionManagementConfigurationSelector  继承自:

AdviceModeImportSelector
该类又实现了:
ImportSelector

 重写了接口:

	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;}}

 AdviceMode :默认属性为:PROXY

 TransactionManagementConfigurationSelector:又导入了两个类,分别为:①AutoProxyRegistrar②ProxyTransactionManagementConfiguration

分析①AutoProxyRegistrar 该类实现接口:ImportBeanDefinitionRegistrar;通过registerBeanDefinitions 向容器中注入了组件,添加后置处理器

	public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {boolean candidateFound = false;Set annTypes = importingClassMetadata.getAnnotationTypes();for (String annType : annTypes) {AnnotationAttributes candidate = AnnotationConfigUtils.attributesFor(importingClassMetadata, annType);if (candidate == null) {continue;}Object mode = candidate.get("mode");Object proxyTargetClass = candidate.get("proxyTargetClass");if (mode != null && proxyTargetClass != null && AdviceMode.class == mode.getClass() &&Boolean.class == proxyTargetClass.getClass()) {candidateFound = true;if (mode == AdviceMode.PROXY) {//注册自动代理AopConfigUtils.registerAutoProxyCreatorIfNecessary(registry);if ((Boolean) proxyTargetClass) {AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);return;}}}}if (!candidateFound && logger.isInfoEnabled()) {String name = getClass().getSimpleName();logger.info(String.format("%s was imported but no annotations were found " +"having both 'mode' and 'proxyTargetClass' attributes of type " +"AdviceMode and boolean respectively. This means that auto proxy " +"creator registration and configuration may not have occurred as " +"intended, and components may not be proxied as expected. Check to " +"ensure that %s has been @Import'ed on the same class where these " +"annotations are declared; otherwise remove the import of %s " +"altogether.", name, name, name));}}

向容器注入组件:InfrastructureAdvisorAutoProxyCreator

	private static BeanDefinition registerOrEscalateApcAsRequired(Class cls, BeanDefinitionRegistry registry, @Nullable Object source) {Assert.notNull(registry, "BeanDefinitionRegistry must not be null");if (registry.containsBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME)) {BeanDefinition apcDefinition = registry.getBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME);if (!cls.getName().equals(apcDefinition.getBeanClassName())) {int currentPriority = findPriorityForClass(apcDefinition.getBeanClassName());int requiredPriority = findPriorityForClass(cls);if (currentPriority < requiredPriority) {apcDefinition.setBeanClassName(cls.getName());}}return null;}//注册一个BeanDefinitionRootBeanDefinition beanDefinition = new RootBeanDefinition(cls);beanDefinition.setSource(source);beanDefinition.getPropertyValues().add("order", Ordered.HIGHEST_PRECEDENCE);beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);registry.registerBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME, beanDefinition);return beanDefinition;}

主要添加一个bean的后置处理器:InfrastructureAdvisorAutoProxyCreator

	@Nullablepublic static BeanDefinition registerAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry, @Nullable Object source) {return registerOrEscalateApcAsRequired(InfrastructureAdvisorAutoProxyCreator.class, registry, source);}

InfrastructureAdvisorAutoProxyCreator 继承类图可见:

SmartInstantiationAwareBeanPostProcessor  -》InstantiationAwareBeanPostProcessor-》BeanPostProcessor

 

在类:AbstractAutoProxyCreator  重写了postProcessBeforeInitialization和postProcessAfterInitialization接口,其中after接口定义如下:

	public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {if (bean != null) {Object cacheKey = getCacheKey(bean.getClass(), beanName);if (this.earlyProxyReferences.remove(cacheKey) != bean) {return wrapIfNecessary(bean, beanName, cacheKey);}}return bean;}//创建代理对象//参数:当前bean,bean名称protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {return bean;}if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {return bean;}if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {this.advisedBeans.put(cacheKey, Boolean.FALSE);return bean;}//判断是否需要创建代理对象,如果需要则创建代理对象.Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);if (specificInterceptors != DO_NOT_PROXY) {this.advisedBeans.put(cacheKey, Boolean.TRUE);Object proxy = createProxy(bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));this.proxyTypes.put(cacheKey, proxy.getClass());return proxy;}this.advisedBeans.put(cacheKey, Boolean.FALSE);return bean;}
 

②:ProxyTransactionManagementConfiguration 是一个配置类,用于注册启用基于代理的注释驱动的事务管理所必需的 Spring 基础结构 bean。注册了三个bean,分别是:

1):BeanFactoryTransactionAttributeSourceAdvisor:事务通知器

	@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;}

2):TransactionAttributeSource:一个事务属性相关来源,知道如何获取事务属性,无论是从配置、源代码级别的元数据属性(如注释)还是其他任何位置,解析注解的属性

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

3):TransactionInterceptor:事务拦截器,具体执行事务的相关内容就在此处。

	@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;}

执行事务操作就在这个拦截器里面:

	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, new CoroutinesInvocationCallback() {@Override@Nullable//重点在这咧public Object proceedWithInvocation() throws Throwable {return invocation.proceed();}@Overridepublic Object getTarget() {return invocation.getThis();}@Overridepublic Object[] getArguments() {return invocation.getArguments();}});}

执行事务调用代码:

		PlatformTransactionManager ptm = asPlatformTransactionManager(tm);final String joinpointIdentification = methodIdentification(method, targetClass, txAttr);if (txAttr == null || !(ptm instanceof CallbackPreferringPlatformTransactionManager)) {// Standard transaction demarcation with getTransaction and commit/rollback calls.//创建一个事务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.//执行被代理的方法retVal = invocation.proceedWithInvocation();}catch (Throwable ex) {// target invocation exception//如果有异常就执行回滚completeTransactionAfterThrowing(txInfo, ex);throw ex;}finally {//清空事务cleanupTransactionInfo(txInfo);}if (retVal != null && 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);}}//提交事务commitTransactionAfterReturning(txInfo);return retVal;}

以上就是spring事务的简单基本原理,不过分深究。核心的核心就是spring的后置处理机制。包括:BeanFactoryPostProcessor和BeanPostProcessor这两个关键的后置处理机制,在初始化前后对bean进行扩展处理。

相关内容

热门资讯

2025中国福州国际招商月丨多... 为传承弘扬“中国福州国际招商月”思想精髓,持续扩大高水平对外开放,有福之州再一次向世界发出了写满诚意...
十五运会女足成年组正赛队伍全部... 来源:新华网 新华社西安5月9日电(记者郑昕)第十五届全国运动会足球项目女子成年组资格赛9日在各赛区...
影像速览!领航战略协作 共促世...   5月7日至10日,习近平主席对俄罗斯进行国事访问并出席在莫斯科举行的纪念苏联伟大卫国战争胜利80...
“最终还是由客户埋单”——德国... 转自:新华社新华财经法兰克福5月11日电(记者刘向 单玮怡 马悦然)位于德国巴登-符腾堡州小镇布雷滕...
一个轮胎引发的险情!高速避障必... 来源:广西交警微发布 近日,南宁市公安局交警支队十五大队民警在兰海高速武鸣服务区路段巡逻时,发现有一...
全国防灾减灾日丨防患未然,一图... 转自:新华网  2025年5月12日是第17个全国防灾减灾日,主题是“人人讲安全、个个会应急——排查...
事发杭州一网红景区!男孩被七八... 本文转自【新闻坊】;杭州的四岭村千岱坑坊友们听你说过吗?这里虽然早已废弃,洞口也已封闭但是在社交平台...
预告|5月12日起,《全民安全... 转自:中华人民共和国应急管理部由应急管理部、中央广播电视总台联合制作的《全民安全公开课》第三季系列节...
进度条刷新!15号线这几个站实... 近日重庆轨道交通15号线迎来了新进展快和小布丁来看看~重庆轨道交通15号线一期建设现场目前,轨道交通...
视频|玉渊谭天:中美会谈前都发...   #中美会谈前都发生了什么##美方为何坐不住了#中美接触进行中,近期美方接连对华滥施关税后,又反复...
相约中国大陆南极世界爱情角!5... 转自:湛江发布情侣朋友们今年520想好怎么过了吗?要不带上你最爱的人来奔赴一场大陆最南端的浪漫之约吧...
乌克兰要求无条件停火30天 最... 乌克兰和欧洲大国要求俄罗斯加入从周一开始的30天“无条件”停火协议,以便就结束战争进行谈判,并表示美...
不止是奔跑!被秦皇岛马拉松暖到... 【不止是奔跑!#被秦皇岛马拉松暖到了#】5月11日,2025秦皇岛马拉松鸣枪开跑,17000名选手在...
陈茂波:首季出口佳因买家赶下单... 格隆汇5月11日|香港政府早前估计第一季本地生产总值(GDP)同比升3.1%,高于市场预期的2.1%...
这个周末邂逅人艺之友 一起“再... 【这个周末#邂逅人艺之友# 一起“再造时光”】5月10日至11日,北京人民艺术剧院联合东城区委区政府...
它博会纳新采购节成交额破350... 转自:上观新闻如何通过创新项目为参展商开辟增量新渠道,是TOPS它博会始终关注的核心问题之一。去年T...
龙江交投:助力龙江旅游经济由“... 新华信用杭州5月11日电(王思凝)作为2025世界品牌莫干山大会的重要组成部分,以“促消费 树品牌 ...
女演员陷“辱华”争议,疑被新剧... 5月10日,女演员李凯馨相关话题连上热搜。日前,一名自称是李凯馨前助理的网友在微博爆料。在其曝光的录...
《三餐四季》广东篇今晚开播:食... 每当人们谈到广东,总有一个绕不开的话题——粤菜。在这个美食天堂里,藏着无数让人念念不忘的老味道。央视...
既当“护企卫士” 也做“贴心管... 转自:中国警察网从精准打击民营企业内部“蛀虫”到出台相关政策打通惠企服务“最后一公里”,近年来,上海...