亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Spring注解@Transactional失效的場景分析

 更新時間:2023年07月18日 11:02:41   作者:京東云開發(fā)者  
在使用Spring中事務(wù)注解@Transactional時會存在幾種場景下該注解失效,即不能按照預(yù)期封裝成一個事務(wù)操作,于是本文文將對該注解進行學(xué)習(xí)并對相關(guān)失效場景進行分析,需要的朋友可以參考下

一、前言

emm,又又又踩坑啦。這次的需求主要是對逾期計算的需求任務(wù)進行優(yōu)化,現(xiàn)有的計算任務(wù)運行時間太長了。簡單描述下此次的問題:在項目中進行多個數(shù)據(jù)庫執(zhí)行操作時,我們期望的是將其整個封裝成一個事務(wù),要么全部成功,或者全部失敗,然而在自測異常場景時發(fā)現(xiàn),里面涉及的第一個數(shù)據(jù)狀態(tài)更新成功了,但是后面的數(shù)據(jù)在插入出現(xiàn)異常,后面查詢數(shù)據(jù)表發(fā)現(xiàn),該數(shù)據(jù)的狀態(tài)已經(jīng)被更新成功啦。

emmm,查看代碼發(fā)現(xiàn)確實是使用了@Transactional注解沒問啊。于是通過查詢網(wǎng)上相關(guān)資料發(fā)現(xiàn),在使用Spring中事務(wù)注解@Transactional時會存在幾種場景下該注解失效,即不能按照預(yù)期封裝成一個事務(wù)操作,于是對該注解進行學(xué)習(xí)并對相關(guān)失效場景進行分析,整理文章如下;

二、@Transactional注解失效場景實例驗證

1、@Transactional注解屬性

屬性類型描述
valueString可選的限定描述符,指定使用的事務(wù)管理器
propagationEnum:Propagation·可選的事務(wù)傳播行為設(shè)置
isolationEnum:Isolation可選的事務(wù)隔離級別設(shè)置
readOnlyboolean讀寫或只讀事務(wù),默認讀寫
timeoutint事務(wù)超時時間設(shè)置
rollbackForClass對象數(shù)組,必須繼承自Throwable導(dǎo)致事務(wù)回滾的異常類數(shù)組
rollbackForClassName類名數(shù)組,必須繼承自Throwable導(dǎo)致事務(wù)回滾的異常類名字數(shù)組
noRollbackForClass對象數(shù)組,必須繼承自Throwable不會導(dǎo)致事務(wù)回滾的異常類數(shù)組
noRollbackForClassName類名數(shù)組,必須繼承自Throwable不會導(dǎo)致事務(wù)回滾的異常類名字數(shù)組

2、 propagation屬性

propagation代表事務(wù)的傳播行為,默認值為Propagation.REQUIRED

屬性描述
Propagation.REQUIRED若當(dāng)前存在事務(wù)則加入該事務(wù),若不存在則創(chuàng)建一個新事務(wù)(默認)
Propagation.SUPPORTS若當(dāng)前存在事務(wù)則加入該事務(wù),若不存在則以非事務(wù)的方式繼續(xù)進行
Propagation.MANDATORY若當(dāng)前存在事務(wù)則加入該事務(wù),若不存在則拋出異常
Propagation.REQUIRES_NEW重新創(chuàng)建一個新的事務(wù),若當(dāng)前存在事務(wù)則暫定當(dāng)前事務(wù)
Propagation.NOT_SUPPORTED以非事務(wù)的方式運行,若當(dāng)前存在事務(wù)則暫定當(dāng)前事務(wù)
Propagation.NEVER以非事務(wù)的方式運行,若當(dāng)前存在事務(wù)則拋出異常
Propagation.NESTED與Propagation.REQUIRED效果一樣

3、 @Transactional注解使用場景?

@Transactional注解可以作用在接口、類、類方法中。

  • 當(dāng)作用于類時,表示所有該類的public方法都配置相同的事務(wù)屬性信息。

  • 當(dāng)作用于方法時,當(dāng)類配置了@Transactional注解,方法也配置了@Transactional,方法的事務(wù)會覆蓋類的事務(wù)配置信息。

  • 當(dāng)作用于接口時,不推薦使用,因為在接口使用@Transactional并且配置了Spring AOP使用CGLib動態(tài)代理將會導(dǎo)致其失效。

4、 @Transactional注解失效場景?

  • @Transactional注解作用在非public修飾的方法上,會失效。

失效原因:在Spring AOP代理時,TransactionInterceptor(事務(wù)攔截器)在目標(biāo)方法執(zhí)行前后進行攔截,DynamicAdvisedInterceptor(CglibAopProxy的內(nèi)部類)的Intercept方法或JDKDynamicAopProxyinvoke方法會間接調(diào)用AbstractFallbackTransationAttributeSourcecomputeTransactionAttribute方法,獲取@Transactional注解的事務(wù)配置信息。

1 protected TransactionAttribute computeTransactionAttribute(Method method,
2    Class<?> targetClass) {
3        // Don't allow no-public methods as required.
4        if (allowPublicMethodsOnly() && !Modifier.isPublic(method.getModifiers())) {
5        return null;
6    }

此方法會檢查目標(biāo)方法的修飾符是否為public,非public作用域則不會獲取@transactional的屬性配置信息。其中protected、private修飾的方法上使用 @Transactional注解,事務(wù)會失效但不會有任何報錯。

  • @Transactional注解屬性propagation設(shè)置錯誤導(dǎo)致注解失效

失效原因:配置錯誤, PROPAGATION_SUPPORTS、PROPAGATION_NOT_SUPPORTED、PROPAGATION_NEVER三種事務(wù)傳播方式不會發(fā)生回滾。

? 實例驗證:寫了一個demo進行測試。demo主要功能如下:執(zhí)行兩次數(shù)據(jù)庫插入操作,并在擴展信息字段中添加備注;

? 運行結(jié)果如下,構(gòu)造的單號不存在訂單查詢?yōu)榭沼|發(fā)異常,觀察數(shù)據(jù)庫發(fā)現(xiàn),第一次數(shù)據(jù)庫插入操作已經(jīng)執(zhí)行成功,故而驗證@Transactional注解失效;

  • @Transactional注解屬性rollbackFor設(shè)置錯誤導(dǎo)致注解失效

rollbackFor可以指定能夠觸發(fā)事務(wù)回滾的異常類型。Spring默認拋出了unchecked異常(繼承自RuntimeException)或者Error才會回滾事務(wù)。若事務(wù)中拋出了其他類型的異常,但卻期望Spring能夠回滾事務(wù),就需要指定rollbackFor屬性,否則就會失效。

  • 同一類中方法調(diào)用,導(dǎo)致@Transactional失效

比如類demo中有方法A和B,方法B中使用@Transactional注解,方法A沒有注解,但是demo類通過方法A調(diào)用方法B,像這種間接調(diào)用會導(dǎo)致方法B中的@Transactional事務(wù)注解失效。

失效原因:只有當(dāng)事務(wù)方法被當(dāng)前類以外的代碼調(diào)用時,才會有Spring生成的代理對象管理。(Spring AOP代理機制造成的)。

? 實例驗證:demo中構(gòu)造場景為在同一個類中,在test方法中添加@Transactional注解,querRiskScore方法中不添加該注解,然后在querRiskScore方法中調(diào)用test方法;觀察下多個插入操作是否會因為異常而中斷回滾;

? 運行結(jié)果如下,還是通過構(gòu)造的單號不存在訂單查詢?yōu)榭沼|發(fā)異常,觀察數(shù)據(jù)庫發(fā)現(xiàn),第一次數(shù)據(jù)庫插入操作已經(jīng)執(zhí)行成功,第二次數(shù)據(jù)插入操作失敗,并沒有因為異常而觸發(fā)事務(wù)操作,故而驗證@Transactional注解方法間的調(diào)用會失效

  • 多線程任務(wù)可能導(dǎo)致@Transaction案例失效

失效原因:線程不屬于Spring托管,故線程不能夠默認使用Spring的事務(wù),也不能獲取Spring注入的bean,在被Spring聲明式事務(wù)管理的方法內(nèi)開啟多線程,多線程內(nèi)的方法不被事務(wù)控制。

  • 異常被方法內(nèi)catch捕獲導(dǎo)致@Transactional失效

比如B方法內(nèi)部拋了異常,而A方法此時try-catch了B方法的異常,則該事務(wù)不能正?;貪L。

失效原因:因為B方法中拋出異常以后,標(biāo)識當(dāng)前事務(wù)需要rollback,但是A方法中由于你手動的捕獲這個異常并進行處理,A方法認為當(dāng)前事務(wù)應(yīng)該正常commit,此時就出現(xiàn)前后不一致,會拋出org.springframework.transaction.UnexpectedRollbackException: Transaction rolled back because it has been marked as rollback-only異常。

? 實例驗證:這個場景的本質(zhì)還是異常被捕獲導(dǎo)致無法正常的拋出,進而導(dǎo)致@Transactional注解無法正常工作,我簡化了下demo實例場景,構(gòu)造場景如下:在querRiskScore方法中添加@Transactional注解,然后在querRiskScore方法中對異常進行捕獲;觀察下多個插入操作是否會因為異常而中斷回滾;

? 運行結(jié)果如下,還是通過構(gòu)造的單號不存在訂單查詢?yōu)榭沼|發(fā)異常,但是我們在方法內(nèi)部對該異常進行捕獲,并未向上層拋出,我們期望的場景是兩次數(shù)據(jù)插入執(zhí)行失敗,但是觀察數(shù)據(jù)庫發(fā)現(xiàn),第一次數(shù)據(jù)庫插入操作已經(jīng)執(zhí)行成功,第二次數(shù)據(jù)插入執(zhí)行成功,與我們的預(yù)期結(jié)果不符,故而驗證@Transactional注解在方法中異常被捕獲的場景中失效;

究其原因:Spring的事務(wù)是在調(diào)用業(yè)務(wù)方法之前開始的,業(yè)務(wù)方法執(zhí)行完畢之后才執(zhí)行commit 或 rollback,事務(wù)是否執(zhí)行取決于是否拋出runtime異常,如果拋出runtime exception并在你的業(yè)務(wù)方法中并沒有catch到的話,事務(wù)就會回滾。

三、“事務(wù)”知識回顧

1.什么是事務(wù)?

事務(wù)(Transaction)是由一系列對系統(tǒng)中數(shù)據(jù)進行訪問與更新的操作組成的一個程序執(zhí)行邏輯單元(Unit)。

通常我們所指的事務(wù)是指數(shù)據(jù)庫事務(wù),使用數(shù)據(jù)庫事務(wù)有以下兩處優(yōu)點:

  • 當(dāng)多個應(yīng)用程序并發(fā)訪問數(shù)據(jù)庫時,事務(wù)可以在這些應(yīng)用程序之間提供一個隔離方法,以防止彼此的操作互相干擾。

  • 事務(wù)為數(shù)據(jù)庫操作序列提供了一個從失敗恢復(fù)到正常狀態(tài)的方法,同時提供了數(shù)據(jù)庫即使在異常狀態(tài)下仍能保持數(shù)據(jù)一致性的方法。

2. 事務(wù)具有的特性?

原子性(Atomicity)、一致性(Consistency)、隔離性(Isolation)和持久性,簡稱事務(wù)的ACID特性。

  • 原子性

事務(wù)的原子性是指事務(wù)必須是一個原子的操作序列單元,即事務(wù)中包含的各項操作在一次執(zhí)行過程中只會出現(xiàn)兩種狀態(tài):全部成功執(zhí)行、全部不執(zhí)行。任何一項操作失敗都將導(dǎo)致整個事務(wù)失敗,同時其他已經(jīng)被執(zhí)行的操作都將被撤銷并回滾,只打所有的操作全部成功,整個事務(wù)才算是成功完成。

  • 一致性

事務(wù)的一致性是指事務(wù)的執(zhí)行不能破壞數(shù)據(jù)庫數(shù)據(jù)的完整性和一致性,一個事務(wù)在執(zhí)行之前和執(zhí)行之后,數(shù)據(jù)庫都必須處于一致性狀態(tài)。也就是說,事務(wù)執(zhí)行的結(jié)果必須是使數(shù)據(jù)庫從一個一致性狀態(tài)轉(zhuǎn)變到另一個一致性狀態(tài),因此當(dāng)數(shù)據(jù)庫只包含成功事務(wù)提交 的結(jié)果時,就能說數(shù)據(jù)庫處于一致性狀態(tài)。而如果數(shù)據(jù)庫系統(tǒng)在運行過程中發(fā)生故障, 有些事務(wù)尚未完成就被迫中斷,這些未完成的事務(wù)對數(shù)據(jù)庫所做的修改有一部分已寫入物理數(shù)據(jù)庫,這時數(shù)據(jù)庫就處于一種不正確的狀態(tài),或者說是不一致的狀態(tài)。

  • 隔離性

事務(wù)的隔離性是指在并發(fā)環(huán)境中,并發(fā)的事務(wù)是相互隔離的,一個事務(wù)的執(zhí)行不能被其他事務(wù)干擾。也就是說,不同的事務(wù)并發(fā)操縱相同的數(shù)據(jù)時,每個事務(wù)都有各自完整的數(shù)據(jù)空間,即一個事務(wù)內(nèi)部的操作及使用的數(shù)據(jù)對其他并發(fā)事務(wù)是隔離的,并發(fā)執(zhí)行的 各個事務(wù)之間不能互相干擾。

  • 持久性

事務(wù)一旦提交,其所做的修改就會永久保存到數(shù)據(jù)庫中,即使數(shù)據(jù)庫發(fā)生故障也不應(yīng)該對其有任何影響。需要注意的是,事務(wù)的持久性不能做到100%的持久,只能從事務(wù)本身的角度來保證永久性,而一些外部原因?qū)е聰?shù)據(jù)庫發(fā)生故障,如硬盤損壞,那么所有提交的數(shù)據(jù)可能都會丟失。

3. 什么是Spring中的事務(wù)?

Spring中同樣提供了很好的事務(wù)管理機制,主要分為編程式事務(wù)聲明式事務(wù)。

  • 編程式事務(wù)

是指在代碼中手動的管理事務(wù)的提交、回滾等操作,代碼侵入性比較強。編程式事務(wù)方式需要開發(fā)者在代碼中手動的管理事務(wù)的開啟、提交、回滾等操作。

public void test() {
      TransactionDefinition def = new DefaultTransactionDefinition();
      TransactionStatus status = transactionManager.getTransaction(def);
      try {
         // 事務(wù)操作
         // 事務(wù)提交
         transactionManager.commit(status);
      } catch (DataAccessException e) {
         // 事務(wù)提交
         transactionManager.rollback(status);
         throw e;
      }
}
  • 聲明式事務(wù)

聲明式事務(wù)是基于AOP面向切面,它將具體業(yè)務(wù)和事務(wù)處理部分解耦,代碼侵入性很低,實際開發(fā)中比較常用。我們常用TX和AOP的xml配置文件方式和@Transactional注解方式。

?聲明式事務(wù)的優(yōu)點:

對代碼無侵入性,方法內(nèi)只需要寫業(yè)務(wù)邏輯,節(jié)省很多代碼量。

?聲明式事務(wù)的缺點:

1、聲明式事務(wù)粒度問題:聲明式事務(wù)的局限就是最小粒度要作用在方法上,且不適合耗時長高并發(fā)場景。

2、聲明式事務(wù)容易被開發(fā)者忽略,當(dāng)事務(wù)嵌套的方法中存在RPC遠程調(diào)用、MQ發(fā)送、Redis更行、文件寫入等操作可能存在以下場景:

? 事務(wù)嵌套的方法中RPC調(diào)用成功了,但是本地事務(wù)回滾導(dǎo)致RPC調(diào)用無法回滾(暫不討論分布式事務(wù))。

?事務(wù)嵌套的方法中遠程調(diào)用會拉長整個事務(wù)周期,導(dǎo)致事務(wù)的數(shù)據(jù)庫連接一致被占用,類似操作過多會導(dǎo)致數(shù)據(jù)庫連接池耗盡。

3、聲明式事務(wù)使用錯誤會導(dǎo)致在某些場景下失效

四、總結(jié)

以上就是Spring注解@Transactional失效的場景分析的詳細內(nèi)容,更多關(guān)于Spring注解@Transactional失效的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Springboot整合Redis的詳細教程分享

    Springboot整合Redis的詳細教程分享

    這篇文章主要為大家詳細介紹了如何利用SpringBoot整合Redis,文中的示例代碼講解詳細,具有很好的參考價值,希望對大家有所幫助
    2022-08-08
  • Spring Boot整合MyBatis-Flex全過程

    Spring Boot整合MyBatis-Flex全過程

    這篇文章主要介紹了Spring Boot整合MyBatis-Flex全過程,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-08-08
  • Java遍歷起止日期中間的所有日期操作

    Java遍歷起止日期中間的所有日期操作

    這篇文章主要介紹了Java遍歷起止日期中間的所有日期操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-09-09
  • SpringBoot中的Redis?緩存問題及操作方法

    SpringBoot中的Redis?緩存問題及操作方法

    這篇文章主要介紹了SpringBoot中的Redis?緩存,本文給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-10-10
  • Spring定時任務(wù)使用及如何使用郵件監(jiān)控服務(wù)器

    Spring定時任務(wù)使用及如何使用郵件監(jiān)控服務(wù)器

    這篇文章主要介紹了Spring定時任務(wù)使用及如何使用郵件監(jiān)控服務(wù)器,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2019-07-07
  • Mybatis分頁插件PageHelper的分頁原理剖析

    Mybatis分頁插件PageHelper的分頁原理剖析

    這篇文章主要介紹了Mybatis分頁插件PageHelper的分頁原理剖析,PageHelper作為一個啟動器,那么就和其他啟動器加載一樣,先讀取spring.factories文件里面配置的類,轉(zhuǎn)成Bean加載本系統(tǒng)中,然后執(zhí)行他的前置后置處理方法,完成初始化,需要的朋友可以參考下
    2023-08-08
  • IDEA 設(shè)置顯示內(nèi)存的使用情況和內(nèi)存回收的方法

    IDEA 設(shè)置顯示內(nèi)存的使用情況和內(nèi)存回收的方法

    這篇文章主要介紹了IDEA 設(shè)置顯示內(nèi)存的使用情況和內(nèi)存回收的方法,本文通過圖文并茂的形式給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-04-04
  • Mybatis 傳輸List的實現(xiàn)代碼

    Mybatis 傳輸List的實現(xiàn)代碼

    本文通過實例代碼給大家介紹了mybatis傳輸list的實現(xiàn)代碼,非常不錯,具有參考借鑒價值,需要的朋友參考下吧
    2017-09-09
  • Java中的static關(guān)鍵字深入理解

    Java中的static關(guān)鍵字深入理解

    這篇文章主要介紹了Java中的static關(guān)鍵字深入理解,文字和代碼列舉了實際例子,有感興趣的同學(xué)可以研究下
    2021-03-03
  • Java報錯:Java.io.FileNotFoundException解決方法

    Java報錯:Java.io.FileNotFoundException解決方法

    這篇文章主要介紹了Java.io.FileNotFoundException的產(chǎn)生原因和解決方法,造成這個報錯的原因可能有文件路徑錯誤、文件被刪除或移動和權(quán)限問題,文中將解決的辦法介紹的非常詳細,需要的朋友可以參考下
    2024-12-12

最新評論