spring本地事務(wù)失效的原因分析
spring本地事務(wù)失效的情況
原因1:未使用@Transactional注解
解決辦法:
確保事務(wù)管理方法上使用了@Transactional注解,這會(huì)告訴Spring該方法應(yīng)該在事務(wù)內(nèi)執(zhí)行。例如:
@Service
public class MyService {
@Transactional
public void doSomething() {
// 執(zhí)行事務(wù)操作
}
}
原因2:配置問題
解決辦法:
檢查Spring事務(wù)管理器的配置。確保Spring配置文件中包含了正確的事務(wù)管理器定義,如DataSourceTransactionManager。例如:
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
原因3:方法調(diào)用問題(重要)
解決辦法:
確保事務(wù)內(nèi)部的方法是通過代理對象調(diào)用的,而不是直接調(diào)用的。Spring的事務(wù)代理只能捕獲通過代理對象的方法調(diào)用來管理事務(wù)。如果在同一個(gè)類中的一個(gè)事務(wù)方法內(nèi)部調(diào)用另一個(gè)事務(wù)方法,事務(wù)可能因?yàn)槔@過了代理對象導(dǎo)致失效。確保這些方法被放在不同的類中或通過自我調(diào)用(如通過AopContext.currentProxy())來確保事務(wù)生效。
1.自我調(diào)用需要引入aop模塊
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
2.啟動(dòng)類開啟動(dòng)態(tài)代理
開啟 aspectj 動(dòng)態(tài)代理功能。以后所有的動(dòng)態(tài)代理都是aspectj創(chuàng)建的(即使沒有接口也可以創(chuàng)建動(dòng)態(tài)代理)
@EnableAspectJAutoProxy
@SpringBootApplication
public class BootTestApplication {
public static void main(String[] args) {
SpringApplication.run(BootTestApplication.class, args);
}
}
3.具體使用
可以直接把我們的service用代理方式創(chuàng)建,例如有一個(gè)BookService:
public BookServiceImpl implements BookService{
BookServiceImpl bookService = (BookServiceImpl) AopContext.currentProxy();
//...
}
這樣同一service中(叫本類方法互調(diào))的方法設(shè)置好的傳播行為將會(huì)生效。
原因4:異常處理問題(重要)
解決辦法:
如果在一個(gè)事務(wù)方法內(nèi)拋出了未捕獲的異常,事務(wù)可能會(huì)被回滾。確保適當(dāng)?shù)靥幚懋惓?,或者在@Transactional注解上使用rollbackFor屬性來指定需要回滾的異常類型。例如:
@Transactional(rollbackFor = Exception.class)
public void doSomething() {
// 執(zhí)行事務(wù)操作
}
原因5:嵌套事務(wù)問題(重要)
解決辦法:
Spring支持嵌套事務(wù),但默認(rèn)情況下,嵌套事務(wù)可能不會(huì)生效。可以在外層方法上使用傳播級別來解決。@Transactional(propagation = Propagation.REQUIRED),以確保嵌套事務(wù)能夠正常工作。
事務(wù)傳播級別
| 傳播級別 | 解釋 |
|---|---|
| REQUIRED(默認(rèn)): | 如果當(dāng)前沒有事務(wù),新建一個(gè)事務(wù),并在方法執(zhí)行期間使用該事務(wù)。如果當(dāng)前已存在一個(gè)事務(wù),加入該事務(wù),成為該事務(wù)的一部分。 |
| REQUIRES_NEW | 無論當(dāng)前是否存在事務(wù),都會(huì)新建一個(gè)事務(wù),原有事務(wù)會(huì)被掛起。在方法執(zhí)行結(jié)束后,新建的事務(wù)提交或回滾,原有事務(wù)會(huì)恢復(fù)執(zhí)行。 |
| SUPPORTS | 如果當(dāng)前存在事務(wù),加入該事務(wù),成為該事務(wù)的一部分。如果當(dāng)前沒有事務(wù),以非事務(wù)方式執(zhí)行。 |
| NOT_SUPPORTED | 以非事務(wù)方式執(zhí)行。如果當(dāng)前存在事務(wù),將其掛起。 |
| MANDATORY | 要求當(dāng)前存在一個(gè)事務(wù),否則會(huì)拋出異常。如果當(dāng)前存在事務(wù),加入該事務(wù)。 |
| NEVER | 以非事務(wù)方式執(zhí)行。如果當(dāng)前存在事務(wù),拋出異常。 |
| NESTED | 如果當(dāng)前存在事務(wù),嵌套一個(gè)新的事務(wù)。如果當(dāng)前沒有事務(wù),行為與REQUIRED相同。嵌套事務(wù)的提交和回滾將影響外部事務(wù)。 |
| NESTED_ROLLBACK_ON_RUNTIME_EXCEPTION(Spring 5.0引入) | 類似于NESTED,但只在運(yùn)行時(shí)異常發(fā)生時(shí)回滾嵌套事務(wù)。 |
兩種使用方式
@Service
public class MyService {
@Transactional(propagation = Propagation.REQUIRED)
public void methodA() {
// ...
}
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void methodB() {
// ...
}
}
<bean id="myService" class="com.example.MyService">
<property name="dataSource" ref="dataSource" />
</bean>
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="methodA" propagation="REQUIRED" />
<tx:method name="methodB" propagation="REQUIRES_NEW" />
</tx:attributes>
</tx:advice>
<aop:config>
<aop:advisor advice-ref="txAdvice" pointcut="execution(* com.example.MyService.*(..))" />
</aop:config>
到此這篇關(guān)于spring本地事務(wù)失效的原因分析的文章就介紹到這了,更多相關(guān)spring本地事務(wù)失效內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
詳解Elasticsearch如何實(shí)現(xiàn)簡單的腳本排序
Elasticsearch?是位于?Elastic?Stack?核心的分布式搜索和分析引擎,可以為所有類型的數(shù)據(jù)提供近乎實(shí)時(shí)的搜索和分析。本文主要介紹了Elasticsearch如何實(shí)現(xiàn)簡單的腳本排序,感興趣的可以了解一下2023-01-01
基于Hutool的圖片驗(yàn)證碼功能模塊實(shí)現(xiàn)
為了提高系統(tǒng)的安全性,防止接口被暴力刷新,驗(yàn)證碼是個(gè)好的手段,圖片驗(yàn)證碼沒有短信驗(yàn)證碼的費(fèi)用,其是個(gè)人開發(fā)者學(xué)習(xí)的重點(diǎn),這篇文章主要介紹了基于Hutool的圖片驗(yàn)證碼功能模塊實(shí)現(xiàn),需要的朋友可以參考下2022-10-10
SpringBoot項(xiàng)目中rest接口定義與參數(shù)傳遞和接收方式
本文介紹了使用RestClient測試接口的兩種方式:form-data和content-type,form-data適用于所有請求方式,但URL長度有限制,content-type只適用于POST/DELETE/PUT請求,處理application/json格式參數(shù),對于參數(shù)較多的情況,建議使用JavaBean接收2026-04-04
spring validation多層對象校驗(yàn)教程
這篇文章主要介紹了spring validation多層對象校驗(yàn)教程,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-10-10
SpringBoot項(xiàng)目統(tǒng)一枚舉轉(zhuǎn)換實(shí)踐過程
文章介紹了在Spring Boot項(xiàng)目中統(tǒng)一枚舉轉(zhuǎn)換的實(shí)踐,通過使用自定義的父枚舉接口和AttributeConverter、ConverterFactory、JsonSerializer和JsonDeserializer等工具,實(shí)現(xiàn)了枚舉與數(shù)據(jù)庫、請求參數(shù)、響應(yīng)參數(shù)和消息參數(shù)之間的自動(dòng)轉(zhuǎn)換2024-12-12
java實(shí)現(xiàn)靜默加載Class示例代碼
這篇文章主要給大家介紹了關(guān)于java實(shí)現(xiàn)靜默加載Class的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家學(xué)習(xí)或者使用java具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧。2017-10-10

