欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

深入理解spring如何管理事務(wù)

 更新時間:2025年01月13日 17:00:19   作者:小貝殼O.o  
文章詳細介紹了Spring框架中的事務(wù)管理機制,包括事務(wù)的基本概念、事務(wù)管理的兩種方式、Spring事務(wù)管理的整體架構(gòu)、事務(wù)配置、聲明式事務(wù)的實現(xiàn)原理、事務(wù)的關(guān)鍵流程、事務(wù)屬性與配置,以及實際開發(fā)中常見的事務(wù)問題和解決方案,感興趣的朋友一起看看吧

Spring 事務(wù)管理概述

最先需要明確一點的是,事務(wù)只是數(shù)據(jù)庫中的一個概念,我們的java程序和數(shù)據(jù)庫進行連接,java程序只是作為數(shù)據(jù)庫的客戶端,本質(zhì)是通過網(wǎng)絡(luò)連接對象connection來間接的操作數(shù)據(jù)庫對sql進行事務(wù)開啟,提交或者回滾。在 Spring 中,事務(wù)管理通常分為兩種方式:編程式事務(wù)聲明式事務(wù)。其中,聲明式事務(wù)(基于注解 @Transactional)是最常用、最直觀的做法。本質(zhì)上,Spring 通過 AOP(面向切面編程)代理機制 來攔截方法調(diào)用,在方法執(zhí)行前后自動開啟、提交或回滾事務(wù)。

1. Spring 事務(wù)管理的整體架構(gòu)

1.1 PlatformTransactionManager接口

  • Spring 為各種數(shù)據(jù)訪問框架提供了不同實現(xiàn)的 PlatformTransactionManager,例如:
    • DataSourceTransactionManager(JDBC)
    • JpaTransactionManager(JPA/Hibernate)
    • HibernateTransactionManager(Hibernate)
    • JpaTransactionManager(JPA)以及其他第三方框架的事務(wù)管理器。
  • 這些事務(wù)管理器對底層資源(數(shù)據(jù)庫連接、Session 等)進行事務(wù)控制,Spring 通過它們來統(tǒng)一管理事務(wù)的開啟、提交與回滾。

1.2 事務(wù)配置(Transaction Configuration)

  • 通過注解 @EnableTransactionManagement 或者在 XML 中聲明 <tx:annotation-driven>,開啟 Spring 對聲明式事務(wù)的支持。
  • 配置好對應(yīng)的 PlatformTransactionManager Bean,讓 Spring 知道使用哪一種事務(wù)管理器。

1.3 聲明式事務(wù)(@Transactional)

  • Spring 在運行時掃描被 @Transactional 注解標記的類或方法,自動為其生成 AOP 代理。
  • 當外部調(diào)用該方法時,會先進入 事務(wù)切面,根據(jù)注解信息決定是否開啟事務(wù),執(zhí)行完畢后再根據(jù)方法執(zhí)行結(jié)果決定提交還是回滾。

1.4 事務(wù)增強(Advice)

  • 事務(wù)的開啟、提交、回滾等邏輯,就封裝在 Spring 提供的事務(wù)增強(TransactionInterceptor)中,通過 AOP 動態(tài)攔截目標方法調(diào)用。

2. Spring 事務(wù)管理的關(guān)鍵流程

以下主要針對 聲明式事務(wù)(基于注解)進行說明:

2.1 Bean 初始化階段

  • Spring 在啟動時,會掃描所有的 Bean,看它們是否使用了 @Transactional 注解。
  • 如果某個類或方法使用了 @Transactional,則由 Spring AOP 或 AspectJ 生成一個代理對象來代替原始對象。
  • 代理對象內(nèi)部持有對真實對象的引用,同時嵌入事務(wù)管理邏輯。

2.2 方法調(diào)用攔截(AOP 代理)

  • 當外部代碼調(diào)用該 Bean 的某個帶有 @Transactional 的方法時,實際上先調(diào)用到 代理對象。
  • 代理對象 會進行一系列判斷,包括:
    • 讀取 @Transactional 的屬性(如 propagation、isolationtimeout、readOnly 等);
    • 判斷當前線程是否已經(jīng)存在事務(wù)(如果有,則根據(jù) propagation 屬性決定如何處理);
    • 如果沒有事務(wù)或者需要新建事務(wù),則調(diào)用 PlatformTransactionManagergetTransaction(...) 開啟一個事務(wù)。

2.3 執(zhí)行目標方法

在事務(wù)已開啟(或已決定加入現(xiàn)有事務(wù))的前提下,代理對象通過反射調(diào)用目標 Bean 的真實方法。目標方法中執(zhí)行數(shù)據(jù)庫操作(或其他資源操作),如果拋出異常,Spring 會捕獲并根據(jù) rollback rules(例如:RuntimeExceptionError 默認回滾等)決定是否回滾。

2.4 提交或回滾事務(wù)

  • 如果目標方法正常結(jié)束,Spring 在退出代理方法前,會調(diào)用 PlatformTransactionManagercommit(...) 方法,提交事務(wù);
  • 如果出現(xiàn)了異常且符合回滾條件,Spring 調(diào)用 PlatformTransactionManagerrollback(...) 方法,回滾事務(wù);
  • 此后,方法調(diào)用才真正返回給調(diào)用者。

2.5 釋放資源

  • 事務(wù)提交或回滾之后,底層數(shù)據(jù)庫連接、Session 等資源會被釋放或歸還到連接池。
  • Spring 也會在內(nèi)部進行相應(yīng)的清理操作,確保線程上下文不再持有錯誤的事務(wù)信息。

3. 事務(wù)屬性與配置

在使用 @Transactional 注解時,可以指定多個屬性來控制事務(wù)行為,比如:

@Transactional(
    propagation = Propagation.REQUIRED,
    isolation = Isolation.DEFAULT,
    timeout = 30,
    readOnly = false,
    rollbackFor = {Exception.class},
    noRollbackFor = {CustomException.class}
)
public void doSomething() {
    // ...
}

propagation - 事務(wù)傳播級別
常見值:REQUIRED、REQUIRES_NEW、SUPPORTS、MANDATORY、NESTED 等,決定當前方法是否需要在已有事務(wù)中執(zhí)行,或新開一個事務(wù)等。

isolation - 事務(wù)隔離級別
READ_UNCOMMITTED, READ_COMMITTED, REPEATABLE_READ, SERIALIZABLE,決定事務(wù)間讀寫數(shù)據(jù)的可見性,防止臟讀、不可重復(fù)讀、幻讀等。

timeout - 超時時間
指定事務(wù)執(zhí)行的最大時間(秒),超過時間未完成則拋出超時異常并回滾。

readOnly - 只讀標志
指示該事務(wù)主要用于查詢操作,可能在某些情況下允許數(shù)據(jù)庫做額外優(yōu)化;某些數(shù)據(jù)庫會忽略此配置。

rollbackFor / noRollbackFor - 回滾策略
指定哪些異常拋出時應(yīng)回滾或不回滾;默認對 運行時異常 和 錯誤 回滾,對編譯異常 不回滾。

4. 實際開發(fā)中事務(wù)的常見問題

同類方法相互調(diào)用失效
如果在方法 A 內(nèi)部調(diào)用方法 B,而 B 也使用了 @Transactional,但這兩者都屬于同一個類,則 B 的事務(wù)不會被代理攔截,導致事務(wù)注解失效??梢酝ㄟ^將 B 提取到另一個 Bean 或使用 AspectJ 等方式解決。

異常類型導致事務(wù)不回滾
Spring 默認對 RuntimeExceptionError 回滾,而對受檢異常(Checked Exception)不回滾,需要在注解中顯式指定 rollbackFor。不小心拋出了“錯誤類型”的異常,就可能導致事務(wù)回滾意外。

讀寫操作混用導致性能或數(shù)據(jù)一致性問題
@Transactional(readOnly = true) 僅作提示,不會強制阻止寫操作。如果在此事務(wù)中執(zhí)行了寫操作或忘記設(shè)置 readOnly = false,就可能引發(fā)數(shù)據(jù)不一致或性能問題。

事務(wù)傳播屬性配置不當
如果不小心將一個需要新事務(wù)的操作配置為 Propagation.REQUIRED 而不是 REQUIRES_NEW,或者反之,則會導致事務(wù)邊界不符預(yù)期,進而出現(xiàn)臟數(shù)據(jù)、鎖競爭等問題。

大事務(wù)導致鎖競爭
在實際項目里,如果單次事務(wù)持續(xù)時間過長,可能會長時間占用數(shù)據(jù)庫鎖,導致鎖競爭或死鎖;需注意將大事務(wù)拆分或優(yōu)化為多次小事務(wù)。

多線程/異步場景下無法共享事務(wù)
Spring 的默認事務(wù)機制基于 ThreadLocal 綁定連接,異步任務(wù)或多線程無法復(fù)用同一事務(wù),如果你在一個方法里開啟多線程進行并發(fā)數(shù)據(jù)庫操作,子線程無法直接繼承主線程的事務(wù)上下文,會拿不到同一個 Connection。

5.spring聲明式事務(wù)執(zhí)行過程示例圖

6.總結(jié)

核心原理

Spring 通過 AOP 代理 攔截帶有 @Transactional 的方法,在方法執(zhí)行前后,根據(jù)注解屬性和底層 PlatformTransactionManager 自動開啟、提交或回滾事務(wù)。

關(guān)鍵組件

  • @Transactional 注解
  • 事務(wù)切面(TransactionInterceptor
  • PlatformTransactionManager
  • TransactionSynchronizationManager(這是 Spring 用于管理“線程上下文”的關(guān)鍵工具類,記錄當前線程關(guān)聯(lián)的事務(wù)資源,如Connect。

同一事務(wù)內(nèi),所有數(shù)據(jù)庫操作都共享此 Connection)

事務(wù)配置

可自定義傳播級別隔離級別、超時、回滾策略等,以滿足不同的業(yè)務(wù)需要。

到此這篇關(guān)于spring如何管理事務(wù)的文章就介紹到這了,更多相關(guān)spring管理事務(wù)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評論