中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Spring中propagation有哪些事務配置

發布時間:2021-06-17 11:56:44 來源:億速云 閱讀:162 作者:chen 欄目:開發技術

這篇文章主要介紹“Spring中propagation有哪些事務配置”,在日常操作中,相信很多人在Spring中propagation有哪些事務配置問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”Spring中propagation有哪些事務配置”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!

Spring propagation7種事務配置

1、簡述

在聲明式的事務處理中,要配置一個切面,其中就用到了propagation,表示打算對這些方法怎么使用事務,是用還是不用,其中propagation有七種配置,REQUIRED、SUPPORTS、MANDATORY、REQUIRES_NEW、NOT_SUPPORTED、NEVER、NESTED。默認是REQUIRED。

2、Spring中七種Propagation類的事務屬性詳解:

REQUIRED:支持當前事務,如果當前沒有事務,就新建一個事務。這是最常見的選擇。

SUPPORTS:支持當前事務,如果當前沒有事務,就以非事務方式執行。

MANDATORY:支持當前事務,如果當前沒有事務,就拋出異常。

REQUIRES_NEW:新建事務,如果當前存在事務,把當前事務掛起。

NOT_SUPPORTED:以非事務方式執行操作,如果當前存在事務,就把當前事務掛起。

NEVER:以非事務方式執行,如果當前存在事務,則拋出異常。

NESTED:支持當前事務,如果當前事務存在,則執行一個嵌套事務,如果當前沒有事務,就新建一個事務。

3、注意事項

這些配置將影響數據存儲,必須根據情況選擇。

@Transactional事務幾點注意及其屬性Propagation的使用

@Transactional事務幾點注意

這里面有幾點需要大家留意:

A. 一個功能是否要事務,必須納入設計、編碼考慮。不能僅僅完成了基本功能就ok。

B. 如果加了事務,必須做好開發環境測試(測試環境也盡量觸發異常、測試回滾),確保事務生效。

C. 以下列了事務使用過程的注意事項,請大家留意。

1. 不要在接口上聲明@Transactional ,而要在具體類的方法上使用 @Transactional 注解,否則注解可能無效。

2.不要圖省事,將@Transactional放置在類級的聲明中,放在類聲明,會使得所有方法都有事務。故@Transactional應該放在方法級別,不需要使用事務的方法,就不要放置事務,比如查詢方法。否則對性能是有影響的。

3.使用了@Transactional的方法,對同一個類里面的方法調用, @Transactional無效。比如有一個類Test,它的一個方法A,A再調用Test本類的方法B(不管B是否public還是private),但A沒有聲明注解事務,而B有。則外部調用A之后,B的事務是不會起作用的。(經常在這里出錯)

4.使用了@Transactional的方法,只能是public,@Transactional注解的方法都是被外部其他類調用才有效,故只能是public。道理和上面的有關聯。故在 protected、private 或者 package-visible 的方法上使用 @Transactional 注解,它也不會報錯,但事務無效。

5.經過在ICORE-CLAIM中測試,效果如下:

A.拋出受查異常XXXException,事務會回滾。

B.拋出運行時異常NullPointerException,事務會回滾。

C.Quartz中,execute直接調用加了@Transactional方法,可以回滾;間接調用,不會回滾。(即上文3點提到的)

D.異步任務中,execute直接調用加了@Transactional方法,可以回滾;間接調用,不會回滾。(即上文3點提到的)

E.在action中加上@Transactional,不會回滾。切記不要在action中加上事務。

F.在service中加上@Transactional,如果是action直接調該方法,會回滾,如果是間接調,不會回滾。(即上文3提到的)

G.在service中的private加上@Transactional,事務不會回滾。

其屬性Propagation的使用:

Spring Transaction中有一個很重要的屬性:Propagation。主要用來配置當前需要執行的方法,與當前是否有transaction之間的關系。

我曉得有點兒抽象,這也是為什么我想要寫這篇博客的原因。看了后面的例子,大家應該就明白了。

一、Propagation取值:

REQUIRED(默認值):在有transaction狀態下執行;如當前沒有transaction,則創建新的transaction;

SUPPORTS:如當前有transaction,則在transaction狀態下執行;如果當前沒有transaction,在無transaction狀態下執行;

MANDATORY:必須在有transaction狀態下執行,如果當前沒有transaction,則拋出異常IllegalTransactionStateException;

REQUIRES_NEW:創建新的transaction并執行;如果當前已有transaction,則將當前transaction掛起;

NOT_SUPPORTED:在無transaction狀態下執行;如果當前已有transaction,則將當前transaction掛起;

NEVER:在無transaction狀態下執行;如果當前已有transaction,則拋出異常IllegalTransactionStateException。

二、REQUIRED與REQUIRED_NEW

上面描述的6種propagation屬性配置中,最難以理解,并且容易在transaction設計時出現問題的是REQUIRED和REQURED_NEW這兩者的區別。當程序在某些情況下拋出異常時,如果對于這兩者不夠了解,就可能很難發現而且解決問題。

下面我們給出三個場景進行分析:

場景一:

ServiceA.java:
 public class ServiceA {
     @Transactional
     public void callB() {
         serviceB.doSomething();
     }
 }
 ServiceB.java
 public class ServiceB {
     @Transactional
     public void doSomething() {
         throw new RuntimeException("B throw exception");
     }
 }

這種情況下,我們只需要在調用ServiceA.callB時捕獲ServiceB中拋出的運行時異常,則transaction就會正常的rollback。

場景二

在保持場景一中ServiceB不變,在ServiceA中調用ServiceB的doSomething時去捕獲這個異常,如下:

 public class ServiceA {
     @Transactional
     public void callB() {
         try {
             serviceB.doSomething();
         } catch (RuntimeException e) {
             System.err.println(e.getMessage());
         }
     }
 }

這個時候,我們再調用ServiceA的callB。程序會拋出org.springframework.transaction.UnexpectedRollbackException: Transaction rolled back because it has been marked as rollback-only這樣一個異常信息。原因是什么呢?

因為在ServiceA和ServiceB中的@Transactional propagation都采用的默認值:REQUREID。

根據我們前面講過的REQUIRED特性,當ServiceA調用ServiceB的時候,他們是處于同一個transaction中。

如下圖所示:

Spring中propagation有哪些事務配置

當ServiceB中拋出了一個異常以后,ServiceB會把當前的transaction標記為需要rollback。

但是ServiceA中捕獲了這個異常,并進行了處理,認為當前transaction應該正常commit。

此時就出現了前后不一致,也就是因為這樣,拋出了前面的UnexpectedRollbackException。

場景三

在保持場景二中ServiceA不變,修改ServiceB中方法的propagation配置為REQUIRES_NEW,如下:

 public class ServiceB {
     @Transactional(propagation = Propagation.REQUIRES_NEW)
     public void doSomething() {
         throw new RuntimeException("B throw exception");
     }
 }

此時,程序可以正常的退出了,也沒有拋出UnexpectedRollbackException。原因是因為當ServiceA調用ServiceB時,serviceB的doSomething是在一個新的transaction中執行的。

如下圖所示:

Spring中propagation有哪些事務配置

所以,當doSomething拋出異常以后,僅僅是把新創建的transaction rollback了,而不會影響到ServiceA的transaction。

ServiceA就可以正常的進行commit。

當然這里把ServiceA和ServiceB放在兩個獨立的transaction是否成立,還需要再多多考慮你的業務需求。

Transaction不是一個新東西了,那對于transaction的使用會不會有一些模式?一些經驗之談呢?答案肯定是有的,以后再說。

到此,關于“Spring中propagation有哪些事務配置”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注億速云網站,小編會繼續努力為大家帶來更多實用的文章!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

明光市| 广安市| 江源县| 长顺县| 大荔县| 汉沽区| 双鸭山市| 淮安市| 东宁县| 海林市| 石嘴山市| 中卫市| 勃利县| 广元市| 石林| 青阳县| 遂平县| 巴楚县| 江西省| 璧山县| 灵台县| 玛沁县| 榆树市| 黄浦区| 上高县| 永嘉县| 泊头市| 河东区| 碌曲县| 舟曲县| 长沙市| 图们市| 咸丰县| 沧源| 增城市| 永定县| 江华| 剑川县| 林西县| 昭通市| 邯郸县|