spring本地事務(wù)失效的原因分析
spring本地事務(wù)失效的情況
原因1:未使用@Transactional注解
解決辦法:
確保事務(wù)管理方法上使用了@Transactional注解,這會告訴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ù)。如果在同一個類中的一個事務(wù)方法內(nèi)部調(diào)用另一個事務(wù)方法,事務(wù)可能因為繞過了代理對象導(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.啟動類開啟動態(tài)代理
開啟 aspectj 動態(tài)代理功能。以后所有的動態(tài)代理都是aspectj創(chuàng)建的(即使沒有接口也可以創(chuàng)建動態(tài)代理)
@EnableAspectJAutoProxy @SpringBootApplication public class BootTestApplication { public static void main(String[] args) { SpringApplication.run(BootTestApplication.class, args); } }
3.具體使用
可以直接把我們的service
用代理方式創(chuàng)建,例如有一個BookService
:
public BookServiceImpl implements BookService{ BookServiceImpl bookService = (BookServiceImpl) AopContext.currentProxy(); //... }
這樣同一service
中(叫本類方法互調(diào))的方法設(shè)置好的傳播行為將會生效。
原因4:異常處理問題(重要)
解決辦法:
如果在一個事務(wù)方法內(nèi)拋出了未捕獲的異常,事務(wù)可能會被回滾。確保適當(dāng)?shù)靥幚懋惓?,或者在@Transactional注解上使用rollbackFor屬性來指定需要回滾的異常類型。例如:
@Transactional(rollbackFor = Exception.class) public void doSomething() { // 執(zhí)行事務(wù)操作 }
原因5:嵌套事務(wù)問題(重要)
解決辦法:
Spring支持嵌套事務(wù),但默認(rèn)情況下,嵌套事務(wù)可能不會生效??梢栽谕鈱臃椒ㄉ鲜褂脗鞑ゼ墑e來解決。@Transactional(propagation = Propagation.REQUIRED)
,以確保嵌套事務(wù)能夠正常工作。
事務(wù)傳播級別
傳播級別 | 解釋 |
---|---|
REQUIRED(默認(rèn)): | 如果當(dāng)前沒有事務(wù),新建一個事務(wù),并在方法執(zhí)行期間使用該事務(wù)。如果當(dāng)前已存在一個事務(wù),加入該事務(wù),成為該事務(wù)的一部分。 |
REQUIRES_NEW | 無論當(dāng)前是否存在事務(wù),都會新建一個事務(wù),原有事務(wù)會被掛起。在方法執(zhí)行結(jié)束后,新建的事務(wù)提交或回滾,原有事務(wù)會恢復(fù)執(zhí)行。 |
SUPPORTS | 如果當(dāng)前存在事務(wù),加入該事務(wù),成為該事務(wù)的一部分。如果當(dāng)前沒有事務(wù),以非事務(wù)方式執(zhí)行。 |
NOT_SUPPORTED | 以非事務(wù)方式執(zhí)行。如果當(dāng)前存在事務(wù),將其掛起。 |
MANDATORY | 要求當(dāng)前存在一個事務(wù),否則會拋出異常。如果當(dāng)前存在事務(wù),加入該事務(wù)。 |
NEVER | 以非事務(wù)方式執(zhí)行。如果當(dāng)前存在事務(wù),拋出異常。 |
NESTED | 如果當(dāng)前存在事務(wù),嵌套一個新的事務(wù)。如果當(dāng)前沒有事務(wù),行為與REQUIRED相同。嵌套事務(wù)的提交和回滾將影響外部事務(wù)。 |
NESTED_ROLLBACK_ON_RUNTIME_EXCEPTION(Spring 5.0引入) | 類似于NESTED,但只在運行時異常發(fā)生時回滾嵌套事務(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)文章
詳解如何將Spring Boot應(yīng)用跑在Docker容器中
這篇文章主要介紹了詳解如何將Spring Boot應(yīng)用跑在Docker容器中,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-07-07SpringBoot中實現(xiàn)文件上傳、下載、刪除功能的步驟
本文將詳細(xì)介紹如何在 Spring Boot 中實現(xiàn)文件上傳、下載、刪除功能,采用的技術(shù)框架包括:Spring Boot 2.4.2、Spring MVC、MyBatis 3.5.6、Druid 數(shù)據(jù)源、JUnit 5 等,文中有詳細(xì)的操作步驟和示例代碼供大家參考,需要的朋友可以參考下2024-01-01Java并發(fā)編程之常用的多線程實現(xiàn)方式分析
這篇文章主要介紹了Java并發(fā)編程之常用的多線程實現(xiàn)方式,結(jié)合實例形式分析了java并發(fā)編程中多線程的相關(guān)原理、實現(xiàn)方法與操作注意事項,需要的朋友可以參考下2020-02-02java DateUtil工具類時間戳類型轉(zhuǎn)換詳解
這篇文章主要為大家詳細(xì)介紹了java DateUtil工具類時間戳類型轉(zhuǎn)換的相關(guān)資料,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-12-12Spring MessageSource獲取消息不符合預(yù)期的問題解決方案
最近我參與的產(chǎn)品要做國際化支持,選擇了用Spring MessageSource來實現(xiàn),這個Spring 框架提供的工具使用很簡單,網(wǎng)上有各種教程文章,這里不做贅述,只說一個實際遇到的問題及解決方案,需要的朋友可以參考下2024-01-01Java并發(fā)編程回環(huán)屏障CyclicBarrier
這篇文章主要介紹了Java并發(fā)編程回環(huán)屏障CyclicBarrier,文章繼續(xù)上文所介紹的Java并發(fā)編程同步器CountDownLatch展開主題相關(guān)內(nèi)容,需要的小伙伴可以參考一下2022-04-04