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

Spring @Transactional 自調(diào)用問(wèn)題深度解析及解決方案

 更新時(shí)間:2025年04月27日 10:21:42   作者:GarfieldFine  
這篇文章主要介紹了Spring @Transactional 自調(diào)用問(wèn)題深度解析及解決方案,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧

Spring @Transactional 自調(diào)用問(wèn)題深度解析

問(wèn)題本質(zhì):自調(diào)用事務(wù)失效

當(dāng)類(lèi)內(nèi)部的方法A調(diào)用同一個(gè)類(lèi)的另一個(gè)帶有@Transactional注解的方法B時(shí),事務(wù)注解不會(huì)生效。這是因?yàn)镾pring的事務(wù)管理是基于A(yíng)OP代理實(shí)現(xiàn)的,而自調(diào)用會(huì)繞過(guò)代理機(jī)制。

原理分析

1. Spring事務(wù)實(shí)現(xiàn)機(jī)制

Spring事務(wù)是通過(guò)動(dòng)態(tài)代理實(shí)現(xiàn)的,有兩種方式:

  • JDK動(dòng)態(tài)代理:基于接口
  • CGLIB代理:基于類(lèi)繼承
// 原始調(diào)用流程(期望的事務(wù)流程)
caller → 代理對(duì)象 → 目標(biāo)對(duì)象.methodB()
// 自調(diào)用時(shí)的實(shí)際流程
caller → 目標(biāo)對(duì)象.methodA() → 目標(biāo)對(duì)象.methodB() [繞過(guò)代理]

2. 自調(diào)用問(wèn)題示例

@Service
public class OrderService {
    public void placeOrder(Order order) {
        // 自調(diào)用導(dǎo)致事務(wù)失效
        validateOrder(order);
        // 其他業(yè)務(wù)邏輯...
    }
    @Transactional
    public void validateOrder(Order order) {
        // 數(shù)據(jù)庫(kù)驗(yàn)證操作...
    }
}

解決方案

方案1:注入自身代理(推薦)

@Service
public class OrderService {
    @Autowired
    private OrderService selfProxy; // 注入代理對(duì)象
    public void placeOrder(Order order) {
        selfProxy.validateOrder(order); // 通過(guò)代理調(diào)用
    }
    @Transactional
    public void validateOrder(Order order) {
        // 事務(wù)生效
    }
}

方案2:重構(gòu)代碼結(jié)構(gòu)

@Service
@RequiredArgsConstructor
public class OrderService {
    private final OrderValidator orderValidator;
    public void placeOrder(Order order) {
        orderValidator.validate(order);
    }
}
@Service
class OrderValidator {
    @Transactional
    public void validate(Order order) {
        // 事務(wù)操作
    }
}

方案3:使用AspectJ模式(編譯時(shí)織入)

# application.properties
spring.aop.proxy-target-class=true
spring.aop.auto=false

技術(shù)深度:Spring事務(wù)代理機(jī)制

代理創(chuàng)建過(guò)程

  • 容器啟動(dòng)時(shí)創(chuàng)建原始Bean
  • 通過(guò)AbstractAutoProxyCreator創(chuàng)建代理
  • 對(duì)@Transactional方法添加攔截器

事務(wù)攔截器調(diào)用棧

TransactionInterceptor.invoke()
→ MethodInvocation.proceed()
→ ReflectiveMethodInvocation.proceed()
→ 最終調(diào)用目標(biāo)方法

生產(chǎn)環(huán)境最佳實(shí)踐

統(tǒng)一事務(wù)邊界

@Service
@Transactional // 類(lèi)級(jí)別注解
public class OrderService {
    public void placeOrder() {
        // 所有public方法都默認(rèn)有事務(wù)
    }
}

事務(wù)監(jiān)控

@Aspect
@Component
public class TransactionMonitor {
    @Around("@annotation(transactional)")
    public Object monitor(ProceedingJoinPoint pjp, Transactional transactional) 
        throws Throwable {
        // 記錄事務(wù)開(kāi)始/結(jié)束
    }
}

異常處理

@Transactional(rollbackFor = {BusinessException.class, TechnicalException.class})
public void process() {
    // 明確指定回滾異常類(lèi)型
}

常見(jiàn)誤區(qū)

私有方法加注解

@Transactional // 無(wú)效!
private void internalMethod() {}

final方法加注解

@Transactional // CGLIB代理下無(wú)效!
public final void finalMethod() {}

同類(lèi)非事務(wù)方法調(diào)用事務(wù)方法

public void methodA() {
    methodB(); // 事務(wù)失效
}
@Transactional
public void methodB() {}

性能考量

  • 代理創(chuàng)建會(huì)增加啟動(dòng)時(shí)間
  • 每個(gè)事務(wù)方法調(diào)用都有攔截開(kāi)銷(xiāo)
  • 長(zhǎng)事務(wù)會(huì)占用數(shù)據(jù)庫(kù)連接

到此這篇關(guān)于Spring @Transactional 自調(diào)用問(wèn)題深度解析的文章就介紹到這了,更多相關(guān)Spring @Transactional 自調(diào)用內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java日常練習(xí)題,每天進(jìn)步一點(diǎn)點(diǎn)(3)

    Java日常練習(xí)題,每天進(jìn)步一點(diǎn)點(diǎn)(3)

    下面小編就為大家?guī)?lái)一篇Java基礎(chǔ)的幾道練習(xí)題(分享)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧,希望可以幫到你
    2021-07-07
  • Java并發(fā)編程之volatile變量介紹

    Java并發(fā)編程之volatile變量介紹

    這篇文章主要介紹了Java并發(fā)編程之volatile變量介紹,volatile提供了弱同步機(jī)制,用來(lái)確保將變量更新通知到其它線(xiàn)程,需要的朋友可以參考下
    2015-04-04
  • IDEA部署Tomcat的超詳細(xì)圖文教程

    IDEA部署Tomcat的超詳細(xì)圖文教程

    最近迫于無(wú)奈從我哪破舊的Eclipse轉(zhuǎn)換到了IDEA,然后就是超多的不習(xí)慣,下面這篇文章主要給大家介紹了關(guān)于IDEA部署Tomcat的相關(guān)資料,文中通過(guò)圖文介紹的非常詳細(xì),需要的朋友可以參考下
    2023-02-02
  • Java 異常處理小結(jié),從入門(mén)到精通

    Java 異常處理小結(jié),從入門(mén)到精通

    這篇文章主要介紹了Java 異常處理小結(jié),從入門(mén)到精通,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-07-07
  • Springboot常用方法參數(shù)注解示例詳解

    Springboot常用方法參數(shù)注解示例詳解

    這篇文章主要介紹了Springboot常用方法參數(shù)注解及示例,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-08-08
  • Java常用測(cè)試工具大全

    Java常用測(cè)試工具大全

    這篇文章主要為大家詳細(xì)介紹了Java常用測(cè)試工具,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來(lái)幫助
    2022-02-02
  • Myeclipse工程發(fā)布時(shí)端口占用問(wèn)題的解決方法

    Myeclipse工程發(fā)布時(shí)端口占用問(wèn)題的解決方法

    這篇文章主要介紹了Myeclipse工程發(fā)布時(shí)端口占用問(wèn)題的解決方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2016-12-12
  • SpringBoot默認(rèn)包掃描機(jī)制與默認(rèn)配置文件詳解

    SpringBoot默認(rèn)包掃描機(jī)制與默認(rèn)配置文件詳解

    這篇文章主要給大家詳細(xì)介紹了SpringBoot默認(rèn)包掃描機(jī)制的原理和示例,以及SpringBoot默認(rèn)配置文件介紹,文章通過(guò)圖文介紹的非常詳細(xì),需要的朋友可以參考下
    2023-08-08
  • springboot如何開(kāi)啟緩存@EnableCaching(使用redis)

    springboot如何開(kāi)啟緩存@EnableCaching(使用redis)

    在Spring Boot項(xiàng)目中集成Redis主要包括添加依賴(lài)到pom.xml、配置application.yml中的Redis連接參數(shù)、編寫(xiě)配置類(lèi)、在啟動(dòng)類(lèi)上添加@EnableCaching注解以及測(cè)試接口的查詢(xún)和緩存驗(yàn)證等步驟,首先,需要在pom.xml中添加spring-boot-starter-data-redis依賴(lài)
    2024-11-11
  • idea sql的xml文件出現(xiàn)紅色警告符的處理方式

    idea sql的xml文件出現(xiàn)紅色警告符的處理方式

    這篇文章主要介紹了idea sql的xml文件出現(xiàn)紅色警告符處理方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-04-04

最新評(píng)論

鄂州市| 龙海市| 六枝特区| 喀喇| 抚宁县| 藁城市| 高邑县| 弥勒县| 安达市| 巴塘县| 灵石县| 青铜峡市| 辽宁省| 偃师市| 曲周县| 崇仁县| 东兰县| 土默特左旗| 涟水县| 大冶市| 新津县| 离岛区| 弋阳县| 海阳市| 广宁县| 贺兰县| 三江| 张家川| 林西县| 英超| 沈阳市| 江华| 庆阳市| 开远市| 安化县| 渭源县| 邵东县| 贵溪市| 霸州市| 凌云县| 和静县|