@Transactional的坑

@Transactional 是 Spring 框架中用于管理事務(wù)的注解,雖然它能極大簡化事務(wù)管理,但在使用過程中也存在一些容易被忽略的 “坑”

  1. 注解失效問題
    1.1 方法非 public
    @Transactional 注解只能應(yīng)用在 public 方法上,若用于 private、protected 或默認(rèn)訪問權(quán)限的方法,注解將失效。因?yàn)?Spring 的 AOP 代理是基于 Java 的訪問控制機(jī)制,非 public 方法無法被代理增強(qiáng)。
    java
    class Service {
    // 此注解無效
    @Transactional
    private void privateMethod() {
    // 業(yè)務(wù)邏輯
    }
    }
    1.2 同類方法調(diào)用
    在同一個(gè)類中,一個(gè)方法調(diào)用另一個(gè)帶有 @Transactional 注解的方法,注解會(huì)失效。這是因?yàn)?Spring 的事務(wù)管理是基于 AOP 代理實(shí)現(xiàn)的,同類方法調(diào)用不會(huì)經(jīng)過代理對象,從而無法觸發(fā)事務(wù)管理邏輯。
    java
    class Service {
    public void outerMethod() {
    innerMethod();
    }

    @Transactional
    public void innerMethod() {
    // 業(yè)務(wù)邏輯
    }
    }
    1.3 異常未被捕獲或異常類型不匹配
    @Transactional 默認(rèn)只對 RuntimeException 及其子類和 Error 進(jìn)行回滾。如果拋出的異常不是 RuntimeException 或 Error,且沒有指定其他需要回滾的異常類型,事務(wù)將不會(huì)回滾。
    java
    @Service
    public class UserService {
    @Transactional
    public void updateUser() throws Exception {
    // 業(yè)務(wù)邏輯
    throw new Exception("自定義異常"); // 不會(huì)觸發(fā)回滾
    }
    }
    可通過 rollbackFor 屬性指定需要回滾的異常類型:
    java
    @Transactional(rollbackFor = Exception.class)
    public void updateUser() throws Exception {
    // 業(yè)務(wù)邏輯
    throw new Exception("自定義異常"); // 會(huì)觸發(fā)回滾
    }

  2. 事務(wù)傳播行為問題
    2.1 傳播行為理解錯(cuò)誤
    @Transactional 注解有多種事務(wù)傳播行為,如 PROPAGATION_REQUIRED、PROPAGATION_SUPPORTS 等。
    PROPAGATION_REQUIRED 是 @Transactional 注解的默認(rèn)事務(wù)傳播行為。當(dāng)一個(gè)帶有 PROPAGATION_REQUIRED 傳播行為的方法被調(diào)用時(shí),如果當(dāng)前存在一個(gè)事務(wù),那么該方法會(huì)加入到這個(gè)事務(wù)中執(zhí)行;如果當(dāng)前沒有事務(wù),那么會(huì)創(chuàng)建一個(gè)新的事務(wù)來執(zhí)行該方法。
    PROPAGATION_SUPPORTS 表示如果當(dāng)前存在一個(gè)事務(wù),那么該方法會(huì)加入到這個(gè)事務(wù)中執(zhí)行;如果當(dāng)前沒有事務(wù),那么該方法會(huì)以非事務(wù)的方式執(zhí)行。適用于一些既可以在事務(wù)中執(zhí)行,也可以不在事務(wù)中執(zhí)行的方法

java
@Transactional(propagation = Propagation.SUPPORTS)
public void someMethod() {
// 業(yè)務(wù)邏輯
}
2.2 嵌套事務(wù)問題
在嵌套事務(wù)中,不同的傳播行為會(huì)影響事務(wù)的提交和回滾。例如,使用 PROPAGATION_NESTED 時(shí),內(nèi)層事務(wù)的回滾可能不會(huì)影響外層事務(wù),但如果內(nèi)層事務(wù)拋出異常且未被捕獲,可能導(dǎo)致外層事務(wù)也回滾。

  1. 數(shù)據(jù)庫隔離級別問題
    3.1 隔離級別不匹配
    @Transactional 注解可以指定數(shù)據(jù)庫隔離級別,如 ISOLATION_READ_COMMITTED、ISOLATION_SERIALIZABLE 等。如果指定的隔離級別與數(shù)據(jù)庫默認(rèn)隔離級別不匹配,可能會(huì)導(dǎo)致性能問題或數(shù)據(jù)不一致。例如,使用 ISOLATION_SERIALIZABLE 會(huì)導(dǎo)致并發(fā)性能大幅下降。
    java
    @Transactional(isolation = Isolation.SERIALIZABLE)
    public void someMethod() {
    // 業(yè)務(wù)邏輯
    }
    3.2 不同數(shù)據(jù)庫隔離級別差異
    不同數(shù)據(jù)庫對隔離級別的支持和實(shí)現(xiàn)可能存在差異,如 MySQL 和 Oracle 對某些隔離級別的處理方式不同。在使用時(shí)需要考慮數(shù)據(jù)庫的特性,避免出現(xiàn)兼容性問題。

  2. 性能問題
    4.1 事務(wù)范圍過大
    如果事務(wù)方法包含大量的業(yè)務(wù)邏輯,尤其是包含一些耗時(shí)操作(如網(wǎng)絡(luò)請求、文件讀寫等),會(huì)導(dǎo)致事務(wù)持有數(shù)據(jù)庫連接的時(shí)間過長,降低數(shù)據(jù)庫的并發(fā)性能,甚至可能引發(fā)死鎖。
    java
    @Transactional
    public void longRunningMethod() {
    // 大量業(yè)務(wù)邏輯和耗時(shí)操作
    }
    4.2 頻繁開啟事務(wù)
    在循環(huán)中頻繁使用 @Transactional 注解開啟事務(wù),會(huì)增加事務(wù)管理的開銷,影響性能。應(yīng)盡量減少不必要的事務(wù)開啟和提交操作。
    java
    @Service
    public class BatchService {
    @Transactional
    public void batchProcess() {
    for (int i = 0; i < 1000; i++) {
    // 業(yè)務(wù)邏輯
    }
    }
    }

  3. 多數(shù)據(jù)源問題
    在使用多數(shù)據(jù)源的情況下,@Transactional 注解需要與相應(yīng)的數(shù)據(jù)源事務(wù)管理器配合使用。如果配置不當(dāng),可能導(dǎo)致事務(wù)管理混亂,無法正確管理不同數(shù)據(jù)源的事務(wù)。
    java
    @Service
    public class MultiDataSourceService {
    @Autowired
    @Qualifier("dataSource1TransactionManager")
    private PlatformTransactionManager transactionManager1;

    @Autowired
    @Qualifier("dataSource2TransactionManager")
    private PlatformTransactionManager transactionManager2;

    // 需要正確配置事務(wù)管理器
    @Transactional(transactionManager = "dataSource1TransactionManager")
    public void someMethod() {
    // 業(yè)務(wù)邏輯
    }
    }

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容