深入理解Spring事務(wù)及傳播機(jī)制之原理解析與實(shí)際應(yīng)用
Spring 框架是一個(gè)流行的Java應(yīng)用程序框架,其中事務(wù)管理是其最重要的特性之一。事務(wù)是指一系列相關(guān)操作的集合,如果其中任何一步失敗,整個(gè)事務(wù)應(yīng)該回滾到之前的狀態(tài)。
Spring 框架提供了一個(gè)豐富的事務(wù)管理功能集合,包括事務(wù)傳播機(jī)制,隔離級(jí)別等。本文將深入了解框架事務(wù)管理的底層原理,特別是事務(wù)傳播機(jī)制的實(shí)現(xiàn)。
事務(wù)概述
事務(wù)是指在數(shù)據(jù)庫(kù)中執(zhí)行的一系列相關(guān)操作。它們必須作為單個(gè)操作單元執(zhí)行,以確保數(shù)據(jù)的一致性和完整性。在Java應(yīng)用程序中,事務(wù)可以使用 JDBC 或 Java Persistence API(JPA)進(jìn)行管理。
Spring 框架支持聲明式和編程式事務(wù)管理。
- 在聲明式事務(wù)管理中,可以使用注釋或XML配置聲明如何管理事務(wù)。
- 在編程式事務(wù)管理中,可以使用編程方式管理事務(wù)。
無(wú)論選擇哪種方式, Spring 框架都提供了一致性的API來(lái)管理事務(wù)。
事務(wù)管理
事務(wù)管理器主要有三個(gè)接口:
- PlatformTransactionManager: 提供了管理事務(wù)的基本操作,如開(kāi)始事務(wù),提交事務(wù)和回滾事務(wù)。
- TransactionDefinition: 提供了事務(wù)的定義,如隔離級(jí)別,超時(shí)和傳播行為。
- TransactionStatus: 提供了事務(wù)的狀態(tài),如是否已提交或已回滾。
Spring 框架提供了許多實(shí)現(xiàn) PlatformTransactionManager 接口的類(lèi), 其中包括:
- DataSourceTransactionManager: 用于在JDBC事務(wù)中使用。
- JpaTransactionManager: 用于在JPA事務(wù)中使用。
- HibernateTransactionManager: 用于在Hibernate事務(wù)中使用。
可以根據(jù)的需要選擇使用哪個(gè)事務(wù)管理器。
事務(wù)傳播機(jī)制
Spring 框架的事務(wù)傳播機(jī)制用于定義在多個(gè)事務(wù)之間如何傳播事務(wù)。例如,如果一個(gè)方法正在一個(gè)具有事務(wù)的上下文中執(zhí)行,而該方法又調(diào)用另一個(gè)方法,那么應(yīng)該如何處理事務(wù)? Spring 框架的事務(wù)傳播機(jī)制定義了這種情況下的行為:
- PROPAGATION_REQUIRED: 如果當(dāng)前存在事務(wù),則加入該事務(wù);否則,創(chuàng)建一個(gè)新事務(wù)。
- PROPAGATION_SUPPORTS: 如果當(dāng)前存在事務(wù),則加入該事務(wù);否則,不使用事務(wù)。
- PROPAGATION_MANDATORY: 如果當(dāng)前存在事務(wù),則加入該事務(wù);否則,拋出異常。
- PROPAGATION_REQUIRES_NEW: 創(chuàng)建一個(gè)新事務(wù),并掛起當(dāng)前事務(wù)(如果存在)。
- PROPAGATION_NOT_SUPPORTED: 不使用事務(wù);如果當(dāng)前存在事務(wù),則掛起該事務(wù)。
- PROPAGATION_NEVER: 不使用事務(wù);如果當(dāng)前存在事務(wù),則拋出異常。
- PROPAGATION_NESTED: 如果當(dāng)前存在事務(wù),則在嵌套事務(wù)中執(zhí)行;否則,創(chuàng)建一個(gè)新事務(wù)。
事務(wù)傳播機(jī)制的默認(rèn)值為 PROPAGATION_REQUIRED。這意味著如果一個(gè)方法在一個(gè)具有事務(wù)的上下文中執(zhí)行,而該方法又調(diào)用另一個(gè)方法,則第二個(gè)方法將加入該事務(wù)。
事務(wù)傳播機(jī)制實(shí)現(xiàn)
事務(wù)傳播機(jī)制是通過(guò) TransactionInterceptor 攔截器來(lái)實(shí)現(xiàn)的。TransactionInterceptor 是一個(gè)AOP攔截器,它攔截方法調(diào)用,并在方法調(diào)用之前和之后啟動(dòng)和提交事務(wù)。
當(dāng)使用 Spring 框架進(jìn)行事務(wù)管理時(shí),需要將 TransactionInterceptor 添加到的應(yīng)用程序上下文中。然后,可以使用 @Transactional 注釋或使用XML配置來(lái)定義事務(wù)傳播行為。
下面是一個(gè)使用 @Transactional 注釋定義事務(wù)傳播行為的示例:
@Transactional(propagation = Propagation.REQUIRED)
public void foo() {
// ...
}
在這個(gè)例子中,foo() 方法使用默認(rèn)的事務(wù)傳播行為 PROPAGATION_REQUIRED。
當(dāng)使用 @Transactional 注釋時(shí), Spring 框架會(huì)將 TransactionInterceptor 添加到的方法上。當(dāng)調(diào)用該方法時(shí),TransactionInterceptor 會(huì)攔截該調(diào)用,并根據(jù)在注釋中指定的事務(wù)傳播行為來(lái)啟動(dòng)事務(wù)。
框架源碼解析
在 Spring 框架中,事務(wù)管理器的實(shí)現(xiàn)主要包括以下幾個(gè)類(lèi):
- AbstractPlatformTransactionManager: 它是PlatformTransactionManager接口的抽象實(shí)現(xiàn)。它定義了事務(wù)的基本操作,如開(kāi)始事務(wù),提交事務(wù)和回滾事務(wù)。
- DataSourceTransactionManager: 它是AbstractPlatformTransactionManager的子類(lèi),它用于在JDBC事務(wù)中使用。
- JpaTransactionManager: 它是AbstractPlatformTransactionManager的子類(lèi),它用于在JPA事務(wù)中使用。
- HibernateTransactionManager: 它是AbstractPlatformTransactionManager的子類(lèi),它用于在Hibernate事務(wù)中使用。
事務(wù)傳播機(jī)制的實(shí)現(xiàn)主要包括以下幾個(gè)類(lèi):
- AbstractFallbackTransactionAttributeSource: 它是TransactionAttributeSource接口的抽象實(shí)現(xiàn)。它定義了如何獲取事務(wù)屬性。
- AnnotationTransactionAttributeSource: 它是AbstractFallbackTransactionAttributeSource的子類(lèi),它用于從注釋中獲取事務(wù)屬性。
- TransactionInterceptor: 它是一個(gè)AOP攔截器,它攔截方法調(diào)用,并在方法調(diào)用之前和之后啟動(dòng)和提交事務(wù)。
事務(wù)傳播機(jī)制的實(shí)現(xiàn)主要是通過(guò) TransactionInterceptor 攔截器來(lái)實(shí)現(xiàn)的。下面是TransactionInterceptor的源代碼:
public class TransactionInterceptor implements MethodInterceptor {
private PlatformTransactionManager transactionManager;
private TransactionAttributeSource transactionAttributeSource;
// ...
@Override
public Object invoke(MethodInvocation invocation) throws Throwable {
TransactionAttributeSource tas = getTransactionAttributeSource();
if (tas == null) {
// no transaction attribute source -> no transaction
return invocation.proceed();
}
Class<?> targetClass = (invocation.getThis() != null ? AopUtils.getTargetClass(invocation.getThis()) : null);
TransactionAttribute txAttr = tas.getTransactionAttribute(invocation.getMethod(), targetClass);
PlatformTransactionManager tm = determineTransactionManager(txAttr);
TransactionInfo txInfo = createTransactionIfNecessary(tm, txAttr, invocation.getMethodIdentification());
Object retVal = null;
try {
retVal = invocation.proceed();
}
catch (Throwable ex) {
// transactional code threw exception -> rollback
completeTransactionAfterThrowing(txInfo, ex);
throw ex;
}
finally {
cleanupTransactionInfo(txInfo);
}
commitTransactionAfterReturning(txInfo);
return retVal;
}
// ...
}
在這個(gè)代碼中,invoke() 方法攔截了方法調(diào)用,并根據(jù)其事務(wù)屬性來(lái)啟動(dòng)事務(wù)。
如果事務(wù)屬性為PROPAGATION_REQUIRED,則創(chuàng)建一個(gè)新事務(wù)或加入當(dāng)前事務(wù)。
如果事務(wù)屬性為PROPAGATION_REQUIRES_NEW,則創(chuàng)建一個(gè)新事務(wù)并掛起當(dāng)前事務(wù)。
如果事務(wù)屬性為PROPAGATION_SUPPORTS,則將不使用事務(wù)。
如果事務(wù)屬性為PROPAGATION_MANDATORY,則將拋出異常。
總結(jié)
Spring 框架的事務(wù)管理是其最重要的特性之一。它提供了一個(gè)豐富的事務(wù)管理功能集合,包括事務(wù)傳播機(jī)制,隔離級(jí)別等。事務(wù)傳播機(jī)制定義了在多個(gè)事務(wù)之間如何傳播事務(wù)。
事務(wù)傳播機(jī)制是通過(guò)TransactionInterceptor攔截器來(lái)實(shí)現(xiàn)的,該攔截器會(huì)攔截方法調(diào)用,并根據(jù)其事務(wù)屬性來(lái)啟動(dòng)事務(wù)。
在使用 Spring 框架進(jìn)行事務(wù)管理時(shí),可以使用@Transactional注釋或使用XML配置來(lái)定義事務(wù)傳播行為。
到此這篇關(guān)于深入理解Spring事務(wù)及傳播機(jī)制之原理解析與實(shí)際應(yīng)用的文章就介紹到這了,更多相關(guān)Spring事務(wù)及傳播內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java核心庫(kù)實(shí)現(xiàn)簡(jiǎn)單的AOP
這篇文章主要介紹了如何用Java核心庫(kù)實(shí)現(xiàn)簡(jiǎn)單的AOP,幫助大家為了更好的理解和學(xué)習(xí)AOP的思想,感興趣的朋友可以了解下2020-08-08
Java編程實(shí)現(xiàn)打地鼠文字游戲?qū)嵗a
這篇文章主要介紹了Java編程實(shí)現(xiàn)打地鼠文字游戲?qū)嵗a,具有一定借鑒價(jià)值,需要的朋友可以參考下。2017-11-11
Mybatis如何實(shí)現(xiàn)@Select等注解動(dòng)態(tài)組合SQL語(yǔ)句
這篇文章主要介紹了Mybatis如何實(shí)現(xiàn)@Select等注解動(dòng)態(tài)組合SQL語(yǔ)句,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-07-07
JAVA中的final關(guān)鍵字用法實(shí)例詳解
這篇文章主要介紹了JAVA中的final關(guān)鍵字用法,結(jié)合實(shí)例形式較為詳細(xì)的分析了Java中的final關(guān)鍵字用于修飾數(shù)據(jù),方法及類(lèi)的具體使用技巧,需要的朋友可以參考下2015-12-12
如何取消IDEA中的項(xiàng)目和Git倉(cāng)庫(kù)的關(guān)聯(lián)
這篇文章介紹了一種取消已經(jīng)開(kāi)啟代碼控制的項(xiàng)目與Git倉(cāng)庫(kù)關(guān)聯(lián)的簡(jiǎn)單方法,首先,在IntelliJ IDEA中打開(kāi)項(xiàng)目,刪除.idea目錄下的vcs.xml文件,這樣IDE界面上的Git圖標(biāo)就會(huì)消失,接下來(lái),打開(kāi)項(xiàng)目所在位置,通過(guò)文件管理器啟用“顯示隱藏的項(xiàng)目”選項(xiàng)2024-10-10
SSH框架網(wǎng)上商城項(xiàng)目第28戰(zhàn)之使用Ajax技術(shù)局部更新商品數(shù)量和總價(jià)
這篇文章主要為大家詳細(xì)介紹了SSH框架網(wǎng)上商城項(xiàng)目第28戰(zhàn)之使用Ajax技術(shù)局部更新商品數(shù)量和總價(jià),感興趣的小伙伴們可以參考一下2016-06-06
Kotlin基礎(chǔ)教程之控制流(順序,分支,循環(huán))
這篇文章主要介紹了Kotlin基礎(chǔ)教程之控制流的相關(guān)資料,需要的朋友可以參考下2017-05-05
springboot+VUE前后端分離實(shí)現(xiàn)疫情防疫平臺(tái)JAVA
本文主要使用了Java、springmvc、VUE、node.js、mybatis、mysql、tomcat、jquery、layui、bootstarp、JavaScript、html、css、jsp、log4j等一些常見(jiàn)的基本技術(shù),實(shí)現(xiàn)一個(gè)疫情防疫小平臺(tái)2021-08-08

