国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

UnexpectedRollbackException解決方案

mating / 4239人閱讀

摘要:在嵌套事務場景中,內層事務的和外層事務的會在外層事務結束時進行提交或回滾。解決方案如果希望內層事務拋出異常時中斷程序執行,直接在外層事務的代碼塊中拋出如果希望程序正常執行完畢,并且希望外層事務結束時全部提交,需要在內層事務中做異常捕獲處理。

前言

最近在項目中發現了一則報錯:“org.springframework.transaction.UnexpectedRollbackException: Transaction rolled back because it has been marked as rollback-only”。根據報錯信息來看是spring框架中的事務管理報錯:事務回滾了,因為它被標記為回滾狀態。

報錯原因

多層嵌套事務中,如果使用了默認的事務傳播方式,當內層事務拋出異常,外層事務捕捉并正常執行完畢時,就會報出rollback-only異常。
spring框架是使用AOP的方式來管理事務,如果一個被事務管理的方法正常執行完畢,方法結束時spring會將方法中的sql進行提交。如果方法執行過程中出現異常,則回滾。spring框架的默認事務傳播方式是PROPAGATION_REQUIRED:如果當前沒有事務,就新建一個事務,如果已經存在一個事務中,加入到這個事務中。
在項目中,一般我們都會使用默認的傳播方式,這樣無論外層事務和內層事務任何一個出現異常,那么所有的sql都不會執行。在嵌套事務場景中,內層事務的sql和外層事務的sql會在外層事務結束時進行提交或回滾。如果內層事務拋出異常e,在內層事務結束時,spring會把事務標記為“rollback-only”。這時如果外層事務捕捉了異常e,那么外層事務方法還會繼續執行代碼,直到外層事務也結束時,spring發現事務已經被標記為“rollback-only”,但方法卻正常執行完畢了,這時spring就會拋出“org.springframework.transaction.UnexpectedRollbackException: Transaction rolled back because it has been marked as rollback-only”。
代碼示例如下:

Class ServiceA {
    @Resource(name = "serviceB")
    private ServiceB b;
    
    @Transactional
    public void a() {
        try {
            b.b()
        } catch (Exception ignore) {
        }
    }
}

Class ServiceB {
    @Transactional
    public void b() {
        throw new RuntimeException();
    }
}

當調用a()時,就會報出“rollback-only”異常。

解決方案

如果希望內層事務拋出異常時中斷程序執行,直接在外層事務的catch代碼塊中拋出e.

如果希望程序正常執行完畢,并且希望外層事務結束時全部提交,需要在內層事務中做異常捕獲處理。

如果希望內層事務回滾,但不影響外層事務提交,需要將內層事務的傳播方式指定為PROPAGATION_NESTED。注:PROPAGATION_NESTED基于數據庫savepoint實現的嵌套事務,外層事務的提交和回滾能夠控制嵌內層事務,而內層事務報錯時,可以返回原始savepoint,外層事務可以繼續提交。

在我的項目中之所以會報“rollback-only”異常的根本原因是代碼風格不一致的原因。外層事務對錯誤的處理方式是返回true或false來告訴上游執行結果,而內層事務是通過拋出異常來告訴上游(這里指外層事務)執行結果,這種差異就導致了“rollback-only”異常。雖然最后事務依然是回滾了,不影響程序對sql的處理,但外層事務的上游本期望返回true和false,卻收到了UnexpectedRollbackException異常,(╯ ̄Д ̄)╯︵ ┻━┻。

附:事務傳播方式

@see org.springframework.transaction.annotation.Propagation

事務傳播方式 說明
PROPAGATION_REQUIRED 如果當前沒有事務,就新建一個事務,如果已經存在一個事務中,加入到這個事務中。這是默認的傳播方式
PROPAGATION_SUPPORTS 支持當前事務,如果當前沒有事務,就以非事務方式執行
PROPAGATION_MANDATORY 使用當前的事務,如果當前沒有事務,就拋出異常
PROPAGATION_REQUIRES_NEW 新建事務,如果當前存在事務,把當前事務掛起
PROPAGATION_NOT_SUPPORTED 以非事務方式執行操作,如果當前存在事務,就把當前事務掛起
PROPAGATION_NEVER 以非事務方式執行,如果當前存在事務,則拋出異常
PROPAGATION_SUPPORTS 支持當前事務,如果當前沒有事務,就以非事務方式執行。
PROPAGATION_NESTED 如果當前存在事務,則在嵌套事務內執行。如果當前沒有事務,則執行與PROPAGATION_REQUIRED類似的操作。

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/77135.html

相關文章

  • CSS三欄布局——多種方法詳解,比較兼容性

    摘要:題目假設高度已知,請寫出三欄布局,其中左欄右欄寬度各為,中間自適應三欄布局的種方案這是一道經典的面試題,下面記錄了布局的種方法。 題目:假設高度已知,請寫出三欄布局,其中左欄、右欄寬度各為300px,中間自適應. 三欄布局的5種方案 這是一道經典的面試題,下面記錄了css布局的5種方法。 三欄布局 * { margin: 0; ...

    馬忠志 評論0 收藏0
  • 實現三欄布局的幾種方法

    摘要:前言三欄布局,顧名思義就是兩邊固定,中間自適應。三欄布局在實際的開發十分常見,比如淘寶網的首頁,就是個典型的三欄布局即左邊商品導航和右邊導航固定寬度,中間的主要內容隨瀏覽器寬度自適應。但網格布局的兼容性不好。 前言 三欄布局,顧名思義就是兩邊固定,中間自適應。三欄布局在實際的開發十分常見,比如淘寶網的首頁,就是個典型的三欄布局:即左邊商品導航和右邊導航固定寬度,中間的主要內容隨瀏覽器寬...

    golden_hamster 評論0 收藏0
  • 實現三欄布局的幾種方法

    摘要:前言三欄布局,顧名思義就是兩邊固定,中間自適應。三欄布局在實際的開發十分常見,比如淘寶網的首頁,就是個典型的三欄布局即左邊商品導航和右邊導航固定寬度,中間的主要內容隨瀏覽器寬度自適應。但網格布局的兼容性不好。 前言 三欄布局,顧名思義就是兩邊固定,中間自適應。三欄布局在實際的開發十分常見,比如淘寶網的首頁,就是個典型的三欄布局:即左邊商品導航和右邊導航固定寬度,中間的主要內容隨瀏覽器寬...

    IamDLY 評論0 收藏0
  • 實現三欄布局的幾種方法

    摘要:前言三欄布局,顧名思義就是兩邊固定,中間自適應。三欄布局在實際的開發十分常見,比如淘寶網的首頁,就是個典型的三欄布局即左邊商品導航和右邊導航固定寬度,中間的主要內容隨瀏覽器寬度自適應。但網格布局的兼容性不好。 前言 三欄布局,顧名思義就是兩邊固定,中間自適應。三欄布局在實際的開發十分常見,比如淘寶網的首頁,就是個典型的三欄布局:即左邊商品導航和右邊導航固定寬度,中間的主要內容隨瀏覽器寬...

    Hegel_Gu 評論0 收藏0

發表評論

0條評論

最新活動
閱讀需要支付1元查看
<