成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

面試突擊:SpringBoot 事務不回滾?怎么解決?

開發 架構
本文我們介紹了 5 種事務不自動回滾的場景和相應的解決方案,開發者應該根據自己的實際情況,選擇合適自己解決方案進行處理。

在 Spring Boot 中,造成事務不自動回滾的場景有很多,比如以下這些:

  1. 非 public 修飾的方法中的事務不自動回滾;
  2. 當 @Transactional 遇上 try/catch 事務不自動回滾;
  3. 調用類內部的 @Transactional 方法事務不自動回滾;
  4. 拋出檢查異常時事務不自動回滾;
  5. 數據庫不支持事務,事務也不會自動回滾。

那么對于上面的這些場景,我們應該如何解決呢?接下來我們一一來看。

1、非 public 方法解決方案

?非 public 方法中事務不回滾的直接原因是,在非 public 方法上添加的 @Transactional 關鍵字是無效的,也就是此方法本身是以非事務的方式運行的,所以它當然不會自動回滾事務了。

因為 @Transactional 使用的是 Spring AOP 實現的,而 Spring AOP 是通過動態代理實現的,而 @Transactional 在生成代理時會判斷,如果方法為非 public 修飾的方法,則不生成代理對象,這樣也就沒辦法自動回滾事務了,它的部分實現源碼如下:

protected TransactionAttribute computeTransactionAttribute(Method method, Class<?> targetClass) {
// Don't allow no-public methods as required.
// 非 public 方法,設置為 null
if (allowPublicMethodsOnly() && !Modifier.isPublic(method.getModifiers())) {
return null;
}
// 后面代碼省略....
}

此問題的解決方案是將方法的權限修飾符改為 public 即可。

2、try/catch 解決方案

當程序中出現了 try/catch 代碼時,事務不會自動回滾,這是因為@Transactional 注解在其實現時,需要感知到異常才會自動回滾,而用戶自行在代碼中加入了 try/catch 之后,@Transactional 就無法感知到異常了,那么也就不能自動回滾事務了。

此問題的解決方案有兩種:一種是在 catch 中將異常重新拋出去,另一種是使用代碼手動將事務回滾。?

解決方案1:將異常重新拋出

解決方案2:使用代碼手動回滾事務

除了解決方案 1 這種不是很友好的回滾事務的方式之外,我們還可以選擇更加友好的,不報錯,但可以回滾事務的方式,其核心實現代碼如下:

3、調用內部 @Transactional 方法解決方案

調用類內部 @Transactional 的方法不自動回滾事務的原因是,@Transactional 是基于 Spring AOP 實現的,而 Spring AOP 又是基于動態代理實現的,而當調用類內部的方法時,不是通過代理對象完成的,而是通過 this 對象實現的,這樣就繞過了代理對象,從而事務就失效了。

此時我們的解決方案是給調用的方法上也加上 @Transactional,具體實現代碼如下:

4、檢查異常的事務解決方案

所謂的檢查異常(Checked Excetion)指的是編譯器要求開發者必須處理的異常,如下圖所示:

?檢查異常不回滾事務的原因是因為,@Transactional 默認只回滾運行時異常 RuntimeException 和 Error,而對于檢查異常默認是不回滾的。

此問題的解決方案是給 @Transactional 注解上,添加 rollbackFor 參數并設置 Exception.class 值即可,具體實現代碼如下:

5、數據庫不支持事務的解決方案

?當我們在程序中添加了 @Transactional,相當于給調用的數據庫發送了:開始事務、提交事務、回滾事務的指令,但是如果數據庫本身不支持事務,比如 MySQL 中設置了使用 MyISAM 引擎,因為它本身是不支持事務的,這種情況下,即使在程序中添加了 @Transactional 注解,那么依然不會有事務的行為,也就不會執行事務的自動回滾了。

在這種情況下,我們只需要設置 MySQL 的引擎為 InnoDB 就可以解決問題了,因為 InnoDB 是支持事務的,當然 MySQL 5.1 之后的默認引擎就是 InnoDB,引擎的設置分為以下兩種情況:

在新建表時設置數據庫引擎:

在修改表時設置數據庫引擎:

PS:也就是數據庫的引擎是和表直接相關的,我們只需要正確的設置引擎之后,事務就可以正常的執行了。

總結

本文我們介紹了 5 種事務不自動回滾的場景和相應的解決方案,開發者應該根據自己的實際情況,選擇合適自己解決方案進行處理。

責任編輯:姜華 來源: 今日頭條
相關推薦

2022-09-12 22:27:05

編程式事務聲明式事務對象

2022-09-19 06:16:23

事務隔離級別Spring

2022-08-01 07:07:15

粘包半包封裝

2022-09-20 22:27:08

事務失效public 修飾

2022-06-29 11:01:05

MySQL事務隔離級別

2022-09-14 19:50:22

事務場景流程

2022-09-27 21:14:54

Spring事務傳播機制

2021-06-07 09:37:05

異常Bug排查

2022-10-09 20:52:19

事務隔離級別傳播機制

2022-09-07 07:05:25

跨域問題安全架構

2022-08-17 07:06:14

SpringBoot配置@Value

2022-02-28 07:01:22

線程中斷interrupt

2022-04-11 07:40:45

synchroniz靜態方法程序

2022-07-11 07:10:48

HTTP協議類型

2022-04-07 07:40:40

線程安全變量

2022-05-05 07:38:32

volatilJava并發

2022-06-06 07:35:26

MySQLInnoDBMyISAM

2009-07-20 18:11:52

iBATIS事務Spring

2022-04-20 07:47:00

notify喚醒線程JVM

2022-07-27 07:36:01

TCP可靠性
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 免费黄色在线 | 午夜视频在线免费观看 | 亚洲第一中文字幕 | 日韩一区二区在线观看视频 | 久久新| 亚洲网站在线观看 | 91一区二区 | 亚洲欧美精品国产一级在线 | 日本视频在线 | 午夜免费视频观看 | 精品久久久久久亚洲综合网 | 国精日本亚洲欧州国产中文久久 | 国产 日韩 欧美 在线 | av免费网站在线观看 | 天天干b | 久久电影一区 | 久久久久久女 | 国产一区 | 久久久久久久久毛片 | 午夜视频网 | 国产午夜影院 | 天天弄天天操 | 国产有码 | 国户精品久久久久久久久久久不卡 | 国产精品乱码一区二三区小蝌蚪 | 成人h视频在线 | 国产传媒毛片精品视频第一次 | 久久久婷婷 | 天天综合91 | 一级大片 | 久久久999国产精品 中文字幕在线精品 | 日日噜噜夜夜爽爽狠狠 | 中文字幕人成人 | 亚洲国产免费 | 国产四区| 一区二区精品 | 欧美日韩国产一区二区三区 | 国产成人精品一区二区三区在线观看 | 国产精品久久久久久吹潮 | 国产 日韩 欧美 在线 | 中文字幕在线观看一区 |