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

Springboot @Transactional使用時(shí)需注意的幾個(gè)問題記錄

 更新時(shí)間:2025年01月06日 11:21:43   作者:moxiaoran5753  
本文詳細(xì)介紹了Spring Boot中使用`@Transactional`注解進(jìn)行事務(wù)管理的多個(gè)方面,包括事務(wù)的隔離級(jí)別(如REPEATABLE_READ)和傳播行為(如REQUIRES_NEW),并指出了在同一個(gè)類中調(diào)用事務(wù)方法時(shí)可能遇到的問題以及解決方案,感興趣的朋友跟隨小編一起看看吧

一、事務(wù)的隔離級(jí)別

在Springboot應(yīng)用中,如果我們想實(shí)現(xiàn)方法一旦執(zhí)行有異常產(chǎn)生,就觸發(fā)事務(wù)回滾,可以在方法上面添加@Transactional注解。如果應(yīng)用采用mysql數(shù)據(jù)庫,雖然mysql本身也有事務(wù)隔離機(jī)制,但在Sping+數(shù)據(jù)庫的應(yīng)用中,會(huì)以Spring事務(wù)為準(zhǔn)。mysql定義的事務(wù)隔離級(jí)別為可重復(fù)讀,在使用 Spring Boot 和 MySQL 的組合時(shí),如果你不特別指定隔離級(jí)別,那么實(shí)際使用的將是 MySQL 的默認(rèn)值 REPEATABLE READ。如果在一些特定場景中不想使用可重復(fù)讀,可通過@Transactional注解的isolation屬性來指定。isolation支持的選項(xiàng)有:

  • ISOLATION_DEFAULT:使用后端數(shù)據(jù)庫默認(rèn)的隔離級(jí)別。
  • ISOLATION_READ_UNCOMMITTED:最低的隔離級(jí)別,允許讀取尚未提交的數(shù)據(jù)變更,可能會(huì)導(dǎo)致臟讀、不可重復(fù)讀或幻讀。
  • ISOLATION_READ_COMMITTED:允許讀取已經(jīng)提交的數(shù)據(jù),可以防止臟讀,但可能會(huì)出現(xiàn)不可重復(fù)讀或幻讀。
  • ISOLATION_REPEATABLE_READ:對同一字段的多次讀取結(jié)果是一致的,除非數(shù)據(jù)是被當(dāng)前事務(wù)本身所修改,可以防止臟讀和不可重復(fù)讀,但幻讀仍可能發(fā)生。
  • ISOLATION_SERIALIZABLE:最高的隔離級(jí)別,完全服從 ACID 的隔離級(jí)別,所有的事務(wù)依次逐個(gè)執(zhí)行,可以防止臟讀、不可重復(fù)讀以及幻讀。

使用示例:

@Transactional(isolation = Isolation.READ_COMMITTED)
public void performTransaction() {
    // 業(yè)務(wù)邏輯代碼
}

 二、事務(wù)的傳播行為

事務(wù)的傳播行為是指當(dāng)一個(gè)事務(wù)方法被另一個(gè)事務(wù)方法調(diào)用時(shí),兩者之間的事務(wù)應(yīng)該如何關(guān)聯(lián)。通過配置不同的傳播行為,可以控制是否應(yīng)該創(chuàng)建新的事務(wù)、加入現(xiàn)有事務(wù)或者以非事務(wù)方式執(zhí)行等。

Spring 提供了七種標(biāo)準(zhǔn)的事務(wù)傳播行為,它們可以通過 @Transactional 注解的 propagation 屬性來指定。以下是這些傳播行為的詳細(xì)說明:

PROPAGATION_REQUIRED (默認(rèn)):
    如果當(dāng)前存在事務(wù),則加入該事務(wù);如果不存在,則創(chuàng)建一個(gè)新的事務(wù)。
   這是最常用的傳播行為,適用于大多數(shù)場景。
PROPAGATION_SUPPORTS
    如果當(dāng)前存在事務(wù),則加入該事務(wù);如果不存在,則以非事務(wù)方式執(zhí)行。
    適合那些對事務(wù)性沒有特別要求的操作,如查詢操作。
PROPAGATION_MANDATORY:
    如果當(dāng)前存在事務(wù),則加入該事務(wù);如果不存在,則拋出異常(IllegalTransactionStateException)。
    用于強(qiáng)制要求在已有事務(wù)中執(zhí)行的方法。
PROPAGATION_REQUIRES_NEW:
    創(chuàng)建一個(gè)新的事務(wù),如果當(dāng)前存在事務(wù),則將當(dāng)前事務(wù)掛起。
    適用于需要獨(dú)立于外部事務(wù)執(zhí)行的業(yè)務(wù)邏輯,確保內(nèi)部操作不會(huì)影響外部事務(wù)的結(jié)果。
PROPAGATION_NOT_SUPPORTED:
    以非事務(wù)方式執(zhí)行操作,如果當(dāng)前存在事務(wù),則將當(dāng)前事務(wù)掛起。
    適合那些明確不需要事務(wù)的操作,如讀取系統(tǒng)配置或發(fā)送郵件等。
PROPAGATION_NEVER:
    以非事務(wù)方式執(zhí)行,如果當(dāng)前存在事務(wù),則拋出異常(IllegalTransactionStateException)。
    用于嚴(yán)格禁止在事務(wù)環(huán)境中執(zhí)行的方法。
PROPAGATION_NESTED:
    如果當(dāng)前存在事務(wù),則在嵌套事務(wù)內(nèi)執(zhí)行;如果不存在,則創(chuàng)建一個(gè)新的事務(wù)。
    嵌套事務(wù)是外部事務(wù)的一部分,但可以獨(dú)立于外部事務(wù)進(jìn)行提交或回滾。這種傳播行為依賴于底層數(shù)據(jù)庫和驅(qū)動(dòng)的支持,例如 MySQL 的 InnoDB 引擎支持保存點(diǎn)(SAVEPOINT),從而實(shí)現(xiàn)嵌套事務(wù)。

 注意事項(xiàng)
性能考慮:選擇合適的傳播行為對于性能優(yōu)化非常重要。例如,PROPAGATION_REQUIRES_NEW 和 PROPAGATION_NOT_SUPPORTED 都會(huì)涉及到事務(wù)的掛起和恢復(fù),這可能會(huì)帶來額外的開銷。
事務(wù)邊界:正確理解事務(wù)的邊界以及傳播行為的影響,有助于避免潛在的問題,如死鎖、數(shù)據(jù)不一致等。
嵌套事務(wù)支持:不是所有的數(shù)據(jù)庫都支持嵌套事務(wù)。使用 PROPAGATION_NESTED 時(shí),請確保你的數(shù)據(jù)庫和驅(qū)動(dòng)程序支持這一特性。
根據(jù)應(yīng)用的具體需求選擇適當(dāng)?shù)膫鞑バ袨椋梢詭椭愀玫毓芾硎聞?wù),確保數(shù)據(jù)的一致性和完整性。

三、Spring事務(wù)中存在的坑

在同一個(gè)類里面,編寫兩個(gè)方法,內(nèi)部調(diào)用的時(shí)候,會(huì)導(dǎo)致事務(wù)設(shè)置失效。原因是沒有用到
代理對象的緣故。具體來說:

Spring 使用 AOP 來實(shí)現(xiàn)事務(wù)管理,它會(huì)為每個(gè)帶有 @Transactional 注解的方法創(chuàng)建一個(gè)代理對象。當(dāng)你通過 Spring 容器獲取這個(gè)類的實(shí)例并調(diào)用其方法時(shí),實(shí)際上是調(diào)用了代理對象的方法,而不是原始類的方法。代理對象負(fù)責(zé)在方法調(diào)用前后插入事務(wù)管理邏輯。

然而,當(dāng)你在一個(gè)類的非靜態(tài)方法中直接調(diào)用另一個(gè) @Transactional 方法時(shí),調(diào)用并沒有經(jīng)過代理對象,而是直接調(diào)用了原始類的方法。因此,事務(wù)管理邏輯不會(huì)被應(yīng)用,導(dǎo)致事務(wù)設(shè)置失效。

方法1:
1)、導(dǎo)入spring-boot-starter-aop依賴
2)、啟動(dòng)類添加注解@EnableAspectJAutoProxy(exposeProxy=true)
3)、事務(wù)使用的地方使用AopContext.currentProxy() 調(diào)用方法。

使用示例:

import org.springframework.aop.framework.AopContext;
@Service
public class MyService {
    @Transactional
    public void transactionalMethod() {
        // 事務(wù)邏輯
    }
    public void performOperation() {
        // 業(yè)務(wù)邏輯
        ((MyService) AopContext.currentProxy()).transactionalMethod();
    }
}

不過這種方式使得代碼更加復(fù)雜且不直觀,因此盡量避免使用,除非絕對必要。

最推薦的做法是將事務(wù)方法移到不同的類中。這樣可以確保每次調(diào)用事務(wù)方法時(shí)都通過代理對象進(jìn)行,從而保證事務(wù)管理生效。具體可參考方法2:

方法2:

@Service
public class MyService {
    @Autowired
    private AnotherService anotherService;
    public void performOperation() {
        // 業(yè)務(wù)邏輯
        anotherService.transactionalMethod();
    }
}
@Service
public class AnotherService {
    @Transactional
    public void transactionalMethod() {
        // 事務(wù)邏輯
    }
}

拓展:@Transactional支持的配置屬性大盤點(diǎn)

除了上面提到的propagation和isolation,@Transactional 注解里邊還支持配置以下屬性:

1. value 或 transactionManager

  • 作用:指定要使用的事務(wù)管理器的名稱。如果你的應(yīng)用程序中有多個(gè)事務(wù)管理器(例如,針對不同的數(shù)據(jù)源),你可以使用這個(gè)屬性來明確指定哪一個(gè)事務(wù)管理器應(yīng)該管理當(dāng)前方法的事務(wù)。
  • 默認(rèn)值"transactionManager",這是 Spring 默認(rèn)的事務(wù)管理器 Bean 名稱。
@Transactional("myTransactionManager")
public void myTransactionalMethod() { // 業(yè)務(wù)邏輯 }

2. readOnly 作用:

指定事務(wù)是否為只讀事務(wù)。只讀事務(wù)通常用于查詢操作,可以提高性能(例如,禁用臟頁寫入等)。

取值

  • false(默認(rèn)):事務(wù)不是只讀的,允許進(jìn)行插入、更新和刪除操作。
  • true:事務(wù)是只讀的,僅允許查詢操作。
@Transactional(readOnly = true)
public List<Entity> findAllEntities() { // 查詢操作 }

3. timeout

作用:定義事務(wù)的超時(shí)時(shí)間(單位為秒)。如果事務(wù)在指定時(shí)間內(nèi)未能完成,Spring 會(huì)自動(dòng)回滾事務(wù)。
默認(rèn)值:-1,表示使用后端數(shù)據(jù)庫或事務(wù)管理器的默認(rèn)超時(shí)設(shè)置。

@Transactional(timeout = 30)
public void longRunningOperation() { // 長時(shí)間運(yùn)行的業(yè)務(wù)邏輯 }

4. rollbackFor

作用:指定哪些異常應(yīng)該觸發(fā)事務(wù)回滾。默認(rèn)情況下,只有未檢查異常(如 RuntimeException 及其子類)會(huì)觸發(fā)回滾。你可以通過這個(gè)屬性指定其他異常類型也應(yīng)觸發(fā)回滾。
取值:一個(gè)或多個(gè)異常類,可以用逗號(hào)分隔。

@Transactional(rollbackFor = {CustomCheckedException.class, AnotherException.class}) public void methodThatMayThrowExceptions() { // 業(yè)務(wù)邏輯 }

5. noRollbackFor

作用:指定哪些異常不應(yīng)該觸發(fā)事務(wù)回滾。默認(rèn)情況下,所有未檢查異常都會(huì)觸發(fā)回滾,但你可以通過這個(gè)屬性指定某些異常不應(yīng)觸發(fā)回滾。
取值:一個(gè)或多個(gè)異常類,可以用逗號(hào)分隔。

@Transactional(noRollbackFor = CustomCheckedException.class)
public void methodThatMayThrowCustomException() { // 業(yè)務(wù)邏輯 }

 6. validation

作用:指定是否在事務(wù)開始之前驗(yàn)證事務(wù)屬性。如果設(shè)置為 true,Spring 會(huì)在事務(wù)開始前檢查事務(wù)屬性是否符合要求,如果不符則拋出異常。
默認(rèn)值:false,即不進(jìn)行驗(yàn)證。

@Transactional(validation = true)
public void validateTransactionalAttributes() { // 業(yè)務(wù)邏輯 }

到此這篇關(guān)于Springboot @Transactional使用時(shí)需注意的幾個(gè)問題的文章就介紹到這了,更多相關(guān)Springboot @Transactional使用內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Spring中@PropertySource的使用方法和運(yùn)行原理詳解

    Spring中@PropertySource的使用方法和運(yùn)行原理詳解

    這篇文章主要介紹了Spring中@PropertySource的使用方法和運(yùn)行原理詳解,PropertySource注解可以方便和靈活的向Spring的環(huán)境容器(org.springframework.core.env.Environment?Environment)中注入一些屬性,這些屬性可以在Bean中使用,需要的朋友可以參考下
    2023-11-11
  • springboot切面添加日志功能實(shí)例詳解

    springboot切面添加日志功能實(shí)例詳解

    在本篇文章里小編給大家整理的是關(guān)于springboot 切面添加日志功能的相關(guān)知識(shí)點(diǎn)內(nèi)容,有需要的朋友們可以參考下。
    2019-09-09
  • Java中volatile?的作用

    Java中volatile?的作用

    這篇文章主要介紹了Java中volatile?的作用,volatile是Java并發(fā)編程的重要組成部分,主要作用是保證內(nèi)存的可見性和禁止指令重排序,下文更多對volatile作用的介紹,需要的小伙伴可以參考一下
    2022-05-05
  • springboot2.x解決運(yùn)行順序及Bean對象注入順序的問題

    springboot2.x解決運(yùn)行順序及Bean對象注入順序的問題

    這篇文章主要介紹了springboot2.x解決運(yùn)行順序及Bean對象注入順序的問題,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-01-01
  • Java直接輸出對象變成@.....的問題及解決

    Java直接輸出對象變成@.....的問題及解決

    這篇文章主要介紹了Java直接輸出對象變成@.....的問題及解決方案,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-09-09
  • 一起來了解Java的File類和IO流

    一起來了解Java的File類和IO流

    這篇文章主要為大家詳細(xì)介紹了Java?File類和IO流,在Java學(xué)習(xí)中,file類與io流是非常重要的部分,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2022-03-03
  • Java SpringBoot整合SpringCloud

    Java SpringBoot整合SpringCloud

    SpringCloud專注于為典型的用例和擴(kuò)展機(jī)制提供良好的開箱即用體驗(yàn),今天小編就帶大家認(rèn)識(shí)SpringCloud都有些什么特點(diǎn),感興趣的小伙伴留下來閱讀全文吧
    2021-09-09
  • java基礎(chǔ)詳細(xì)筆記之異常處理

    java基礎(chǔ)詳細(xì)筆記之異常處理

    異常是程序中的一些錯(cuò)誤,但并不是所有的錯(cuò)誤都是異常,并且錯(cuò)誤有時(shí)候是可以避免的,下面這篇文章主要給大家介紹了關(guān)于java基礎(chǔ)詳細(xì)筆記之異常處理的相關(guān)資料,需要的朋友可以參考下
    2022-03-03
  • MybatisPlus+Postgresql整合的幾個(gè)坑及解決

    MybatisPlus+Postgresql整合的幾個(gè)坑及解決

    這篇文章主要介紹了MybatisPlus+Postgresql整合的幾個(gè)坑及解決方案,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-03-03
  • Spring?AOP?的實(shí)現(xiàn)和切點(diǎn)表達(dá)式的實(shí)現(xiàn)方式

    Spring?AOP?的實(shí)現(xiàn)和切點(diǎn)表達(dá)式的實(shí)現(xiàn)方式

    本文給大家介紹了Spring?AOP的基本概念、通知類型、切點(diǎn)表達(dá)式和切面優(yōu)先級(jí),并通過示例代碼展示了如何實(shí)現(xiàn)這些功能,感興趣的朋友跟隨小編一起看看吧
    2024-12-12

最新評論