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

面試突擊:什么情況會導致@Transactional事務失效?

開發 前端
@Transactional 會在方法執行前,會自動開啟事務;在方法成功執行完,會自動提交事務;如果方法在執行期間,出現了異常,那么它會自動回滾事務。

一個程序中不可能沒有事務,而 Spring 中,事務的實現方式分為兩種:編程式事務和聲明式事務,又因為編程式事務實現相對麻煩,而聲明式事務實現極其簡單,所以在日常項目中,我們都會使用聲明式事務 @Transactional 來實現事務。

@Transactional 使用極其簡單,只需要在類上或方法上添加 @Transactional 關鍵字,就可以實現事務的自動開啟、提交或回滾了,它的基礎用法如下:

@Transactional 
@RequestMapping("/add")
public int add(UserInfo userInfo) {
int result = userService.add(userInfo);
return result;
}

@Transactional 執行流程

@Transactional 會在方法執行前,會自動開啟事務;在方法成功執行完,會自動提交事務;如果方法在執行期間,出現了異常,那么它會自動回滾事務。

然而,就是看起來極其簡單的 @Transactional,卻隱藏著一些“坑”,這些坑就是我們今天要講的主題:導致 @Transactional 事務失效的常見場景有哪些?

在開始之前,我們先要明確一個定義,什么叫做“失效”?

本文中的“失效”指的是“失去(它的)功效”,也就是當 @Transactional 不符合我們預期的結果時,我們就可以說 @Transactional 失效了。

那 @Transactional 失效的場景有哪些呢?接下來我們一一來看。

1.非 public 修飾的方法

當 @Transactional 修飾的方法為非 public 時,事務就失效了,比如以下代碼當遇到異常之后,不能自動實現回滾:

@RequestMapping("/save")
int save(UserInfo userInfo) {
// 非空效驗
if (userInfo == null ||
!StringUtils.hasLength(userInfo.getUsername()) ||
!StringUtils.hasLength(userInfo.getPassword()))
return 0;
// 執行添加操作
int result = userService.save(userInfo);
System.out.println("add 受影響的行數:" + result);
int num = 10 / 0; // 此處設置一個異常
return result;
}

以上程序的運行結果如下:

當程序出現運行時異常時,我們預期的結果是事務應該實現自動回滾,也就是添加用戶失敗,然而當我們查詢數據庫時,卻發現事務并未執行回滾操作,數據庫的數據如下圖所示:

2.timeout 超時

當在 @Transactional 上,設置了一個較小的超時時間時,如果方法本身的執行時間超過了設置的 timeout 超時時間,那么就會導致本來應該正常插入數據的方法執行失敗,示例代碼如下:

@Transactional(timeout = 3) // 超時時間為 3s
@RequestMapping("/save")
int save(UserInfo userInfo) throws InterruptedException {
// 非空效驗
if (userInfo == null ||
!StringUtils.hasLength(userInfo.getUsername()) ||
!StringUtils.hasLength(userInfo.getPassword()))
return 0;
int result = userService.save(userInfo);
return result;
}

UserService 的 save 方法實現如下:

public int save(UserInfo userInfo) throws InterruptedException {
// 休眠 5s
TimeUnit.SECONDS.sleep(5);
int result = userMapper.add(userInfo);
return result;
}

以上程序的運行結果如下:

數據庫沒有正確的插入數據,如下圖所示:

3.代碼中有 try/catch

在前面 @Transactional 的執行流程中,我們提到:當方法中出現了異常之后,事務會自動回滾。然而,如果在程序中加了 try/catch 之后,@Transactional 就不會自動回滾事務了,示例代碼如下:

@Transactional
@RequestMapping("/save")
public int save(UserInfo userInfo) throws InterruptedException {
// 非空效驗
if (userInfo == null ||
!StringUtils.hasLength(userInfo.getUsername()) ||
!StringUtils.hasLength(userInfo.getPassword()))
return 0;
int result = userService.save(userInfo);
try {
int num = 10 / 0; // 此處設置一個異常
} catch (Exception e) {
}
return result;
}

以上程序的運行結果如下:

此時,查詢數據庫我們發現,程序并沒有執行回滾操作,數據庫中被成功的添加了一條數據,如下圖所示:

4.調用類內部 @Transactional 方法

當調用類內部的 @Transactional 修飾的方法時,事務是不會生效的,示例代碼如下:

@RequestMapping("/save")
public int saveMappping(UserInfo userInfo) {
return save(userInfo);
}
@Transactional
public int save(UserInfo userInfo) {
// 非空效驗
if (userInfo == null ||
!StringUtils.hasLength(userInfo.getUsername()) ||
!StringUtils.hasLength(userInfo.getPassword()))
return 0;
int result = userService.save(userInfo);
int num = 10 / 0; // 此處設置一個異常
return result;
}

以上代碼我們在添加方法 save 中添加了 @Transactional 聲明式事務,并且添加了異常代碼,我們預期的結果是程序出現異常,事務進行自動回滾,以上程序的執行結果如下:

然而,當我們查詢數據庫時發現,程序執行并不符合我們的預期,添加的數據并沒有進行自動回滾操作,如下圖所示:

5.數據庫不支持事務

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

總結

當聲明式事務 @Transactional 遇到以下場景時,事務會失效:

  • 非 public 修飾的方法;
  • timeout 設置過小;
  • 代碼中使用 try/catch 處理異常;
  • 調用類內部 @Transactional 方法;
  • 數據庫不支持事務。

參考 & 鳴謝

www.cnblogs.com/frankyou/p/12691463.html

責任編輯:武曉燕 來源: 今日頭條
相關推薦

2022-06-27 07:23:44

MySQL常量優化

2022-09-20 22:27:08

事務失效public 修飾

2021-11-08 15:17:15

變量Defer 失效

2024-11-20 08:00:00

死鎖多線程編程

2022-04-13 20:53:15

Spring事務管理

2023-09-27 16:22:51

SpringMySQL原子性

2012-04-25 09:24:40

Android

2025-04-11 01:00:00

線程鎖Spring事務

2021-04-15 08:01:27

Spring聲明式事務

2022-01-18 06:59:50

HashMap循環底層

2023-05-05 07:39:04

Spring事務面試

2020-08-07 15:15:01

Java內存泄漏面試

2023-09-28 09:07:54

注解失效場景

2021-12-13 11:12:41

Spring事務失效

2022-09-12 22:27:05

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

2022-09-19 06:16:23

事務隔離級別Spring

2022-09-25 22:12:07

事務SpringBoot

2022-10-09 20:52:19

事務隔離級別傳播機制

2022-08-09 09:34:32

Spring開發

2022-08-08 17:38:45

Spring策略事務
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 精品欧美一区免费观看α√ | 日本一区二区三区四区 | 九九热这里只有精品6 | 成人免费看电影 | 五月综合激情在线 | 亚洲视频二 | 久草免费视 | 国产欧美日韩在线观看 | 拍戏被cao翻了h承欢 | 综合久久综合久久 | 国产日本精品视频 | 亚洲综合区 | a级毛片免费高清视频 | 国产福利91精品一区二区三区 | 色综合久久久 | 国产精品久久久久久久久久久新郎 | 日韩一区二区在线播放 | 精品国产三级 | 自拍 亚洲 欧美 老师 丝袜 | 久久视频免费观看 | 亚洲综合在线播放 | 日韩福利在线 | 香蕉久久a毛片 | 最新日韩欧美 | 欧美在线综合 | 亚洲精品国产第一综合99久久 | 日韩精品在线免费观看视频 | 美女国产| 日韩午夜影院 | 日韩国产精品一区二区三区 | 综合第一页 | 中文字幕视频一区二区 | 欧美国产亚洲一区二区 | 久久人爽 | 欧美在线a | 日韩精品一区二区三区在线播放 | 久久久免费在线观看 | 欧美激情精品久久久久久变态 | 99久久精品免费视频 | 精品国产乱码久久久久久丨区2区 | 免费视频中文字幕 |