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

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

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

一、前言

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

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

二、@Transactional注解失效場景實(shí)例驗(yàn)證

1、@Transactional注解屬性

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

2、 propagation屬性

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

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

3、 @Transactional注解使用場景?

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

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

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

  • 當(dāng)作用于接口時(shí),不推薦使用,因?yàn)樵诮涌谑褂聾Transactional并且配置了Spring AOP使用CGLib動(dòng)態(tài)代理將會(huì)導(dǎo)致其失效。

4、 @Transactional注解失效場景?

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

失效原因:在Spring AOP代理時(shí),TransactionInterceptor(事務(wù)攔截器)在目標(biāo)方法執(zhí)行前后進(jìn)行攔截,DynamicAdvisedInterceptor(CglibAopProxy的內(nèi)部類)的Intercept方法或JDKDynamicAopProxyinvoke方法會(huì)間接調(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    }

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

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

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

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

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

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

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

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

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

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

? 實(shí)例驗(yàn)證:demo中構(gòu)造場景為在同一個(gè)類中,在test方法中添加@Transactional注解,querRiskScore方法中不添加該注解,然后在querRiskScore方法中調(diào)用test方法;觀察下多個(gè)插入操作是否會(huì)因?yàn)楫惓6袛嗷貪L;

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

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

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

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

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

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

? 實(shí)例驗(yàn)證:這個(gè)場景的本質(zhì)還是異常被捕獲導(dǎo)致無法正常的拋出,進(jìn)而導(dǎo)致@Transactional注解無法正常工作,我簡化了下demo實(shí)例場景,構(gòu)造場景如下:在querRiskScore方法中添加@Transactional注解,然后在querRiskScore方法中對(duì)異常進(jìn)行捕獲;觀察下多個(gè)插入操作是否會(huì)因?yàn)楫惓6袛嗷貪L;

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

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

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

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

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

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

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

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

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

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

  • 原子性

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

  • 一致性

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

  • 隔離性

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

  • 持久性

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

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

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

  • 編程式事務(wù)

是指在代碼中手動(dòng)的管理事務(wù)的提交、回滾等操作,代碼侵入性比較強(qiáng)。編程式事務(wù)方式需要開發(fā)者在代碼中手動(dòng)的管理事務(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ù)處理部分解耦,代碼侵入性很低,實(shí)際開發(fā)中比較常用。我們常用TX和AOP的xml配置文件方式和@Transactional注解方式。

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

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

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

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

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

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

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

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

四、總結(jié)

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

相關(guān)文章

  • SpringBoot中TransactionTemplate事務(wù)管理的實(shí)現(xiàn)

    SpringBoot中TransactionTemplate事務(wù)管理的實(shí)現(xiàn)

    Spring Boot提供了多種方式來管理事務(wù),其中之一是使用TransactionTemplate,本文主要介紹了SpringBoot中TransactionTemplate事務(wù)管理的實(shí)現(xiàn),具有一定的參考價(jià)值,感興趣的可以了解一下
    2024-04-04
  • 詳細(xì)總結(jié)Java堆棧內(nèi)存、堆外內(nèi)存、零拷貝淺析與代碼實(shí)現(xiàn)

    詳細(xì)總結(jié)Java堆棧內(nèi)存、堆外內(nèi)存、零拷貝淺析與代碼實(shí)現(xiàn)

    零拷貝,這是個(gè)耳熟能詳?shù)拿~,是開發(fā)崗面試中經(jīng)常提及的問題.最近在回顧Netty的基礎(chǔ)原理,還是把NIO中關(guān)于堆外內(nèi)存的知識(shí)點(diǎn)過了一遍,這里就針對(duì)堆棧內(nèi)存 堆外內(nèi)存和零拷貝這幾個(gè)概念以及相關(guān)知識(shí)做一下記錄,需要的朋友可以參考下
    2021-05-05
  • SpringBoot整合clickhouse配置多分片地址的示例詳解

    SpringBoot整合clickhouse配置多分片地址的示例詳解

    這篇文章主要為大家詳細(xì)介紹了SpringBoot整合clickhouse配置多分片地址的相關(guān)方法,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2025-10-10
  • Spring觀察者模式之事件發(fā)布訂閱實(shí)現(xiàn)和源碼詳解

    Spring觀察者模式之事件發(fā)布訂閱實(shí)現(xiàn)和源碼詳解

    這篇文章主要介紹了Spring觀察者模式之事件發(fā)布訂閱實(shí)現(xiàn)和源碼詳解,Spring認(rèn)為發(fā)布訂閱主題,其實(shí)可以理解為事件驅(qū)動(dòng)的編碼,先來實(shí)現(xiàn)以下Spring容器中的事件發(fā)布訂閱,需要的朋友可以參考下
    2024-01-01
  • java開啟遠(yuǎn)程debug竟有兩種參數(shù)(最新推薦)

    java開啟遠(yuǎn)程debug竟有兩種參數(shù)(最新推薦)

    這篇文章主要介紹了java開啟遠(yuǎn)程debug竟有兩種參數(shù),本文結(jié)合實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-07-07
  • SpringBoot實(shí)現(xiàn)延遲消息的兩種方案及對(duì)象詳解

    SpringBoot實(shí)現(xiàn)延遲消息的兩種方案及對(duì)象詳解

    在日常業(yè)務(wù)開發(fā)中,延遲消息是高頻剛需場景,幾乎所有中大型項(xiàng)目都會(huì)用到,很多同學(xué)第一反應(yīng)是用 定時(shí)任務(wù)輪詢數(shù)據(jù)庫,但這種方式存在性能差、延遲不準(zhǔn)、數(shù)據(jù)庫壓力大、實(shí)時(shí)性低等致命問題,完全不適合生產(chǎn)環(huán)境,所以本文給大家介紹了SpringBoot實(shí)現(xiàn)延遲消息的兩種方案
    2026-05-05
  • 詳解如何用Java實(shí)現(xiàn)對(duì)m3u8直播流抽幀

    詳解如何用Java實(shí)現(xiàn)對(duì)m3u8直播流抽幀

    抽幀(frame extraction)是指從視頻流中提取一些特定的幀,通常是關(guān)鍵幀或者隨機(jī)幀,以供后續(xù)處理。這篇文章主要為大家介紹了如何用Java實(shí)現(xiàn)對(duì)m3u8直播流抽幀,需要的可以參考一下
    2023-03-03
  • 關(guān)于maven打包時(shí)的報(bào)錯(cuò): Return code is: 501 , ReasonPhrase:HTTPS Required

    關(guān)于maven打包時(shí)的報(bào)錯(cuò): Return code is: 501 , ReasonPhrase:HTTPS Requ

    這篇文章主要介紹了關(guān)于maven打包時(shí)的報(bào)錯(cuò): Return code is: 501 , ReasonPhrase:HTTPS Required,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-09-09
  • SpringMVC中的攔截器與異常處理機(jī)制詳解

    SpringMVC中的攔截器與異常處理機(jī)制詳解

    這篇文章主要介紹了SpringMVC中的攔截器與異常處理機(jī)制詳解,SpringMVC的攔截器類似于Servlet開發(fā)中的過濾器Filter,用于對(duì)處理器進(jìn)行預(yù)處理和后處理,需要的朋友可以參考下
    2024-01-01
  • spring-data-jpa中findOne與getOne的區(qū)別說明

    spring-data-jpa中findOne與getOne的區(qū)別說明

    這篇文章主要介紹了spring-data-jpa中findOne與getOne的區(qū)別說明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-11-11

最新評(píng)論

辽源市| 北海市| 成武县| 黎川县| 武川县| 龙泉市| 河北区| 平定县| 洞口县| 商南县| 宜川县| 巩义市| 通许县| 台中市| 扶余县| 乐至县| 银川市| 堆龙德庆县| 巴林右旗| 南开区| 浦县| 石家庄市| 宝清县| 都兰县| 曲阜市| 台安县| 吉安县| 封开县| 肥乡县| 郴州市| 萝北县| 龙泉市| 邵武市| 班玛县| 越西县| 上栗县| 张家港市| 渭南市| 临夏县| 枣强县| 盖州市|