Spring調(diào)用this導(dǎo)致事務(wù)失效的三種解決方案
一、為什么this調(diào)用會(huì)導(dǎo)致事務(wù)失效?
Spring 的聲明式事務(wù)基于 AOP 代理 實(shí)現(xiàn):
- Spring 為你的 Bean 創(chuàng)建一個(gè) 代理對(duì)象
- 事務(wù)邏輯在代理對(duì)象中織入
- 只有 通過代理對(duì)象調(diào)用方法 才會(huì)觸發(fā)事務(wù)
失效場(chǎng)景
@Service
public class OrderService {
public void createOrder() {
// 直接調(diào)用
this.saveOrder(); // ? 不經(jīng)過代理
}
@Transactional
public void saveOrder() {
// 數(shù)據(jù)庫操作
}
}
調(diào)用路徑:
createOrder() → this.saveOrder()
這里沒有經(jīng)過 Spring 代理 → 事務(wù)不會(huì)生效。
二、如何保證事務(wù)生效?
方案一:通過 Spring 代理對(duì)象調(diào)用(推薦?????)
方法1:注入自身代理
@Service
public class OrderService {
@Autowired
private OrderService orderService; // 注入代理對(duì)象
public void createOrder() {
orderService.saveOrder(); // ? 通過代理調(diào)用
}
@Transactional
public void saveOrder() {
}
}
原理:Spring 注入的是代理對(duì)象,而不是原始對(duì)象。
方法2:使用 AopContext 獲取代理(需開啟暴露代理)
① 開啟配置
@EnableAspectJAutoProxy(exposeProxy = true)
② 調(diào)用方式
public void createOrder() {
((OrderService) AopContext.currentProxy()).saveOrder();
}
適合不想注入自身的場(chǎng)景。
方案二:拆分到不同 Service(最佳實(shí)踐?????)
這是企業(yè)項(xiàng)目最推薦的結(jié)構(gòu)設(shè)計(jì)。
@Service
public class OrderService {
@Autowired
private OrderTxService orderTxService;
public void createOrder() {
orderTxService.saveOrder();
}
}
@Service
public class OrderTxService {
@Transactional
public void saveOrder() {
}
}
? 更清晰
? 職責(zé)單一
? 更利于維護(hù) & 擴(kuò)展
這是大型系統(tǒng)常見架構(gòu)方式。
方案三:使用編程式事務(wù)(不常用)
@Autowired
private TransactionTemplate transactionTemplate;
public void createOrder() {
transactionTemplate.execute(status -> {
saveOrder();
return null;
});
}
適用于:
- 需要精細(xì)控制事務(wù)
- 復(fù)雜業(yè)務(wù)流程
但日常開發(fā)不推薦優(yōu)先使用。
以上就是Spring調(diào)用this導(dǎo)致事務(wù)失效的三種解決方案的詳細(xì)內(nèi)容,更多關(guān)于Spring調(diào)用this導(dǎo)致事務(wù)失效的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Java的validation參數(shù)校驗(yàn)代碼實(shí)例
這篇文章主要介紹了Java的validation參數(shù)校驗(yàn)代碼實(shí)例,Validation參數(shù)校驗(yàn)是指在程序運(yùn)行中對(duì)傳進(jìn)來的參數(shù)進(jìn)行合法性檢查,以保證程序的正確性和安全性,需要的朋友可以參考下2023-10-10
詳解Java中Dijkstra(迪杰斯特拉)算法的圖解與實(shí)現(xiàn)
Dijkstra(迪杰斯特拉)算法是典型的單源最短路徑算法,用于計(jì)算一個(gè)節(jié)點(diǎn)到其他所有節(jié)點(diǎn)的最短路徑。本文將詳解該算法的圖解與實(shí)現(xiàn),需要的可以參考一下2022-05-05
Log4j2?重大漏洞編譯好的log4j-2.15.0.jar包下載(替換過程)
Apache?開源項(xiàng)目?Log4j?的遠(yuǎn)程代碼執(zhí)行漏洞細(xì)節(jié)被公開,由于?Log4j?的廣泛使用,該漏洞一旦被攻擊者利用會(huì)造成嚴(yán)重危害,下面小編給大家?guī)砹薒og4j2?重大漏洞編譯好的log4j-2.15.0.jar包下載,感興趣的朋友一起看看吧2021-12-12
Java 對(duì)象序列化 NIO NIO2詳細(xì)介紹及解析
這篇文章主要介紹了Java 對(duì)象序列化 NIO NIO2詳細(xì)介紹及解析的相關(guān)資料,序列化機(jī)制可以使對(duì)象可以脫離程序的運(yùn)行而對(duì)立存在,需要的朋友可以參考下2017-02-02
Springboot中如何自動(dòng)轉(zhuǎn)JSON輸出
這篇文章主要介紹了Springboot中如何自動(dòng)轉(zhuǎn)JSON輸出,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-06-06
Java并發(fā)編程:CountDownLatch與CyclicBarrier和Semaphore的實(shí)例詳解
這篇文章主要介紹了Java并發(fā)編程:CountDownLatch與CyclicBarrier和Semaphore的實(shí)例詳解的相關(guān)資料,需要的朋友可以參考下2017-09-09

