最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

spring聲明式事務(wù)@Transactional底層工作原理

 更新時間:2022年02月24日 08:53:32   作者:kl  
這篇文章主要為大家介紹分析spring聲明式事務(wù)@Transactional底層工作原理,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步早日升職加薪

引言

寫這篇博文有個來由,是為了解決博主遇到的多數(shù)據(jù)源的事務(wù)問題(用不了JTA),所以深入到spring-tx的源碼去學(xué)習(xí)了一番,非常有收獲,最后博主的分布式事務(wù)問題也迎刃而解了,這個文章算個開篇,關(guān)于如何處理多數(shù)據(jù)源事務(wù),待下文分解。本文涉及到的技術(shù)包含spring aop的使用、spring bean生命周期等,如果能夠真正理解Transactional的工作原理,對排查事務(wù)相關(guān)的問題有非常大的幫助。

spring-tx版本:5.0.2

工作機制簡述

先來看一張官方的事務(wù)簡圖:

spring定義了@Transactional注解,基于AbstractBeanFactoryPointcutAdvisor、StaticMethodMatcherPointcut、MethodInterceptor的aop編程模式,增強了添加@Transactional注解的方法。同時抽象了事務(wù)行為為PlatformTransactionManager(事務(wù)管理器)、TransactionStatus(事務(wù)狀態(tài))、TransactionDefinition(事務(wù)定義)等形態(tài)。最終將事務(wù)的開啟、提交、回滾等邏輯嵌入到被增強的方法的前后,完成統(tǒng)一的事務(wù)模型管理。

事務(wù)AOP核心類釋義

@Transactional

事務(wù)注解,用于定位aop的切入點,事務(wù)注解里包含了完整事務(wù)的所有基本屬性,常見的屬性如:

transactionManager:事務(wù)管理器

propagation:傳播行為定義,枚舉類型,是spring獨有的事務(wù)行為設(shè)計,默認為PROPAGATION_REQUIRED(支持當前事務(wù),不存在則新建)

isolation:隔離級別,對應(yīng)數(shù)據(jù)庫的隔離級別實現(xiàn),mysql默認的隔離級別是 read-committed

timeout:超時時間,默認使用數(shù)據(jù)庫的超時,mysql默認的事務(wù)等待超時為5分鐘

readOnly:是否只讀,默認是false

rollbackFor:異常回滾列表,默認的是RuntimeException異常回滾

TransactionAttribute

事務(wù)屬性抽象接口類,承載了@Transactional注解里的所有屬性,實現(xiàn)類的繼承關(guān)系如下類結(jié)構(gòu)圖,這個實例在被注解解析器創(chuàng)建好后,會在事務(wù)上下文中傳遞

SpringTransactionAnnotationParser

見名知意,這個類是spring的事務(wù)注解解析器,實現(xiàn)自TransactionAnnotationParser接口,是spring管理的事務(wù)解析器,用于解析@Transactional注解,將注解里的屬性設(shè)置到TransactionAttribute的實現(xiàn)類屬性里。除了這個,另還有兩個實現(xiàn),分別是JTA事務(wù)注解解析器,和EJB事務(wù)注解管理解析器,區(qū)別是解析的注解不同,spring是@Transactional,jta是javax.transaction.Transactional,EJB是javax.ejb.TransactionAttribute。這個地方應(yīng)用和apache dubbo2.7.x版本解析dubbo的@service注解是一樣一樣的。關(guān)鍵代碼如下,通過AnnotatedElementUtils類,這個類在spring-core包下,找到注解屬性集AnnotationAttributes,如果不為空,則包裝成事務(wù)屬性集返回

@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

見名知意,這個類是注解事務(wù)屬性集的源,怎么理解呢?spring抽象了獲取事務(wù)屬性集的行為,而AnnotationTransactionAttributeSource正是@Transactional注解方式的事務(wù)屬性集收集實現(xiàn)。SpringTransactionAnnotationParser就是作用于這個里面,用于發(fā)現(xiàn)@Transactiona注解的方法

TransactionAttributeSourcePointcut

也是見名知意,Pointcut屬于aop的概念范疇,需要了解spring aop的知識才能看明白,這個就是@Transactional注解的切點,AnnotationTransactionAttributeSource作用于此,用于尋找@Transactiona注解的方法,關(guān)鍵代碼如下:

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

TransactionInterceptor

事務(wù)的攔截器。aop編程里,有了切入點Pointcut,就要有通知advice,我們熟悉的spring aop里有前置、后置、環(huán)繞、異常等通知類型,TransactionInterceptor屬于自定義通知模型實現(xiàn),實現(xiàn)自Advice接口,類似于環(huán)繞通知,具體見類結(jié)構(gòu)圖,如下:

核心方法如下:

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正確的增強了,運行的時候都會進入到這個方法里面,如果你發(fā)現(xiàn)事務(wù)不生效啊等等問題,可以從這里開始定位真實原因

BeanFactoryTransactionAttributeSourceAdvisor

事務(wù)增強器,用于增強添加了@Transactional注解的方法,上面提到的這些核心類,最終都作用于這里,用于尋找@Transactional注解的方法和織入事務(wù)處理邏輯

ProxyTransactionManagementConfiguration

代理事務(wù)管理的配置類,上面介紹的這些事務(wù)aop編程相關(guān)的在這個里面組合配置生效的,同時,如果你有特殊的個性化的需求,也可以自定義注冊這個里面的實例。比如我嫌棄@Transactional注解太長了,想用@Tx注解。沒關(guān)系,直接定義個TransactionAttributeSource實現(xiàn),解析@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;
	}
}

事務(wù)抽象核心類釋義

PlatformTransactionManager

平臺事務(wù)管理器,這是Spring事務(wù)基礎(chǔ)設(shè)施中的中心接口。它定義了三個最最基本的事務(wù)方法,getTransaction獲取事務(wù),包含了事務(wù)開啟的行為,commit提交事務(wù),rollback回滾事務(wù)。代碼如下:

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中并沒有提供真正的實現(xiàn)類,只提供了一個抽象派生類AbstractPlatformTransactionManager,并建議其他實現(xiàn)基于這個派生類,因為它預(yù)先實現(xiàn)了定義的傳播行為并處理事務(wù)同步處理。子類必須為底層事務(wù)的特定狀態(tài)實現(xiàn)模板方法,例如:begin、suspend、resume、commit等。我們平時常見的實現(xiàn)有:JpaTransactionManager、JtaTransactionManager、DataSourceTransactionManager等。事務(wù)管理器和事務(wù)aop處理的邏輯本身沒有任何耦合,只需將PlatformTransactionManager實例注冊到spring上下文中即可,事務(wù)攔截器會通過獲取到@Transactional里的transactionManager屬性去上下文中尋找事務(wù)管理器,并將其緩存起來,見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

事務(wù)狀態(tài)抽象,用這個類的實現(xiàn)來維護當前的事務(wù)狀態(tài),spring-tx里提供了默認的實現(xiàn)DefaultTransactionStatus。一般情況下這個不需要我們關(guān)心,它和PlatformTransactionManager是成對存在的,心細的你可能已經(jīng)發(fā)現(xiàn)了,PlatformTransactionManager里的三個事務(wù)行為傳遞的就是TransactionStatus。我們知道事務(wù)aop增強了添加@Transactional的方法,在執(zhí)行方法前調(diào)用PlatformTransactionManager.getTransaction開啟事務(wù),之后調(diào)用commit方法提交事務(wù),提交事務(wù)的入?yún)ransactionStatus就是開啟事務(wù)獲得的。參見TransactionAspectSupport.java里的createTransactionIfNecessary方法

TransactionDefinition

事務(wù)定義,對應(yīng)了TransactionAttribute,最終通過aop得到的TransactionAttribute里的屬性會被傳遞到TransactionDefinition里,所以TransactionDefinition里也包含了所有事務(wù)相關(guān)的屬性,PlatformTransactionManager.getTransaction正是通過這個里面的屬性去獲取的事務(wù)。AbstractPlatformTransactionManager派生類里也是通過這個里面的屬性去判斷協(xié)調(diào)spring的事務(wù)傳播行為的

結(jié)語

當梳理完spring-tx模塊的整個結(jié)構(gòu)和工作方式后,仿佛拉開了spring事務(wù)管理的面紗,很多事務(wù)的執(zhí)行細節(jié)一覽無余。很多事務(wù)相關(guān)的問題也就很容易解釋了。比如常見的類中的方法直接調(diào)用方法事務(wù)不生效等問題,以及可以非常清晰的理解spring的傳播行為的真正含義等。最后預(yù)告下,spring對于多數(shù)據(jù)源的事務(wù)處理解決方案ChainedTransactionManager

以上就是spring聲明式事務(wù)@Transactional底層工作原理的詳細內(nèi)容,更多關(guān)于spring聲明式事務(wù)@Transactional工作原理的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Spring Reactor基本介紹和案例解析

    Spring Reactor基本介紹和案例解析

    Spring Reactor 是一個響應(yīng)式編程框架,非常適合類似 MXN 這樣的流程編排系統(tǒng),也是 Java 中異步編程的一種補充,這篇文章主要介紹了Spring Reactor基本介紹和案例解析,需要的朋友可以參考下
    2024-07-07
  • SpringBoot數(shù)據(jù)訪問的實現(xiàn)

    SpringBoot數(shù)據(jù)訪問的實現(xiàn)

    本文主要介紹了SpringBoot數(shù)據(jù)訪問的實現(xiàn),引入各種xxxTemplate,xxxRepository來簡化我們對數(shù)據(jù)訪問層的操作,感興趣的可以了解一下
    2023-11-11
  • Java中的Static class詳解及實例代碼

    Java中的Static class詳解及實例代碼

    這篇文章主要介紹了 Java中的Static class詳解及實例代碼的相關(guān)資料,在Java中我們可以有靜態(tài)實例變量、靜態(tài)方法、靜態(tài)塊。類也可以是靜態(tài)的,需要的朋友可以參考下
    2017-03-03
  • Spring Boot中單例類實現(xiàn)對象的注入方式

    Spring Boot中單例類實現(xiàn)對象的注入方式

    這篇文章主要介紹了Spring Boot中單例類實現(xiàn)對象的注入方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-08-08
  • 基于Maven的pom.xml文件詳解

    基于Maven的pom.xml文件詳解

    下面小編就為大家?guī)硪黄贛aven的pom.xml文件詳解。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-08-08
  • Java中的CountDownLatch同步工具類使用解析

    Java中的CountDownLatch同步工具類使用解析

    這篇文章主要介紹了Java中的CountDownLatch使用解析,CountDownLatch初始化的時候必須指定一個count,await方法會一直阻塞直到調(diào)用countdown方法,count為0,當count為0時,所有的等待線程都會被釋放,需要的朋友可以參考下
    2023-12-12
  • Java如何將處理完異常之后的程序能夠從拋出異常的地點向下執(zhí)行?

    Java如何將處理完異常之后的程序能夠從拋出異常的地點向下執(zhí)行?

    今天小編就為大家分享一篇關(guān)于Java如何將處理完異常之后的程序能夠從拋出異常的地點向下執(zhí)行?,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2019-04-04
  • MyEclipse+Tomcat配置詳解(圖文)

    MyEclipse+Tomcat配置詳解(圖文)

    這篇文章主要介紹了MyEclipse+Tomcat配置詳解(圖文),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2019-01-01
  • 基于Java HashMap的死循環(huán)的啟示詳解

    基于Java HashMap的死循環(huán)的啟示詳解

    本篇文章是對Java HashMap的死循環(huán)進行了詳細的分析介紹,需要的朋友參考下
    2013-05-05
  • Java一些常見的出錯異常處理方法總結(jié)

    Java一些常見的出錯異常處理方法總結(jié)

    下面小編就為大家?guī)硪黄狫ava一些常見的出錯異常處理方法總結(jié)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2016-06-06

最新評論

壤塘县| 平谷区| 天祝| 西充县| 肥西县| 诏安县| 临海市| 祁门县| 伊金霍洛旗| 库车县| 海阳市| 临西县| 柳河县| 宁陵县| 抚顺县| 吉木萨尔县| 元朗区| 杭锦旗| 枣阳市| 襄樊市| 临武县| 襄汾县| 宁安市| 宿松县| 武义县| 乾安县| 吉隆县| 彭阳县| 荥经县| 濮阳县| 依兰县| 特克斯县| 通城县| 上饶县| 金湖县| 时尚| 平果县| 青铜峡市| 息烽县| 宝应县| 德惠市|