精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

盤點Spring事務失效的4種寫法及解決方案,Review代碼再也不慌了

開發 前端
事務是我們日常開發工作中無法避免的一個功能,深刻理解事務的運行機制,正確使用事務的聲明式操作,才能讓我們寫出更健壯的代碼。

1、非運行時異常導致事務無法回滾

我們知道,Spring是通過AOP的方式來實現事務的,而在處理事務的過程中,Spring只有捕獲到RuntimeException或者Error的時候才會觸發回滾操作,如果我們在代碼中拋出的是非運行時異常,而又沒有特殊配置的話,事務就會無法回滾。

下面我們以一個簡單的例子,復現一下這種情況,以及針對這種情況的解決方案。

本文Springboot版本:2.7.6,數據源為MySQL。

首先創建一個測試用的User對象:

@Data
public class User {
@TableId(type = IdType.AUTO)
private Integer id;
private String name;
private String pwd;
}

建表語句:

CREATE TABLE user  (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
`pwd` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB;

測試邏輯:往user表插入一條數據,如果插入成功,就拋出exception異常,測試數據是否回滾。

@Service
@AllArgsConstructor
public class DemoService {
private final UserMapper userMapper;

@Transactional
public ResponseEntity<Object> addUser(User user) throws Exception {
int insert = this.userMapper.insert(user);
if (insert > 0) {
throw new Exception("異常回滾測試");
}
return ResponseEntity.ok().build();
}
}

新建測試方法:

@Test
public void addUserTest() throws Exception {
User user = new User();
user.setName("測試");
user.setPwd("123456");
this.demoService.addUser(user);
}

運行測試方法,從控制臺可以看到,我們手動指定的異常被成功拋出。

但是,當異常發生時,事務并沒有被回滾,數據依然被插入到了數據庫。

解決辦法:
1,將異常包裝成運行時異常:throw new RuntimeException("異常回滾測試");

2,在@Transactional指定回滾的異常類型,@Transactional(rollbackFor = Exception.class)。

一般來說,使用第二種方式會更清晰一些,但是有些朋友往往會忘記手動指定回滾的異常類型,進而導致非預期的bug產生。

2、通過this調用本類事務方法導致的事務無法回滾

隨著業務的發展,核心業務代碼會越來越多,同一個方法也會越寫越長。我們為了使代碼邏輯更加高內聚低耦合,會將功能相同的代碼進行封裝成一個個的子方法。

但是,如果我們對事務的運行機制了解不透徹,隨意在同一個類中通過this調用事務方法,就可能導致非預期的bug。

@Service
@RequiredArgsConstructor
public class DemoService {
private final UserMapper userMapper;
public ResponseEntity<Object> addUser(User user){
//注意這一行
this.doAddUser(user);
return ResponseEntity.ok().build();
}

@Transactional(rollbackFor = Exception.class)
public void doAddUser(User user) {
int insert = this.userMapper.insert(user);
if (insert > 0) {
throw new RuntimeException("測試添加異常回滾");
}
}
}

如以上代碼所示,在addUser方法中調用了事務方法doAddUser,如果數據插入成功,就拋出一個異常,測試數據是否能夠回滾。

通過測試用例可以看到,異常已經拋出,但是數據庫中卻成功的插入了數據,我們期望的數據并沒有回滾。

原因探究:

原因其實很簡單,通過this方法調用時,Spring的代理沒能起作用,事務自然也就無法介入,關于這一點的原理在之前的文章中也有分析過,感興趣的朋友可以去看一看。

有的朋友可能會說,項目的代碼已經是這樣了,再將老方法重寫到新類中也不現實,有沒有辦法改動較小的方式呢?

其實很簡單,現在事務失效的原因是代理失效,那么想辦法讓代理重新生效就行了。

我們在本類中注入一個當前對象,這個對象可以被Spring代理,那么這個對象的方法自然也可以被代理。

@Service
@RequiredArgsConstructor
public class DemoService {
private final UserMapper userMapper;
@Resource
private DemoService self;
public ResponseEntity<Object> addUser(User user){
//通過self引用使代理生效
this.self.doAddUser(user);
return ResponseEntity.ok().build();
}

@Transactional(rollbackFor = Exception.class)
public void doAddUser(User user) {
int insert = this.userMapper.insert(user);
if (insert > 0) {
throw new RuntimeException("測試添加異常回滾");
}
}
}

3、被聲明的事務方法是private類型

這種錯誤在博主剛工作時遇到挺多次的,不過現在現代IDE已經越來越智能了,對于這種情況會直接給出錯誤提示,所以這里提出這種錯誤只是告訴大家,事務方法是不能聲明為private的。

至于為什么不能是private,那自然還是和代理有關了。

4、嵌套事務異常導致事務被提前關閉而報錯

當使用嵌套事務時,需要明確指定事務的傳播范圍。

@Service
@RequiredArgsConstructor
public class DemoService {
private final UserMapper userMapper;
@Resource
private DemoService self;

@Transactional(rollbackFor = Exception.class)
public ResponseEntity<Object> addUser(User user) {
int insert = this.userMapper.insert(user);
if (insert > 0) {
try {
this.self.update(user);
} catch (Exception e) {
System.out.println("即使更新異常也不要影響添加數據");
}
}
return ResponseEntity.ok().build();
}

@Transactional(rollbackFor = Exception.class)
public void update(User user) {
user.setPwd("666666");
int update = this.userMapper.updateById(user);
if (update > 0) {
throw new RuntimeException("測試更新數據回滾");
}
}
}

如以上代碼,我們添加完一條數據之后,嘗試將密碼更新為666666,并且希望即使更新異常,也不要影響添加操作。

然而運行測試用例,我們會得到這樣一條錯誤信息:
org.springframework.transaction.UnexpectedRollbackException: Transaction rolled back because it has been marked as rollback-only。

什么意思呢?就是當Spring處理事務時,發現事務已經被回滾了。

這是因為我們并沒有指定事務的傳播行為,默認情況下,Spring的事務傳播是REQUIRED,即:如果本來有事務,則加入該事務,如果沒有事務,則創建新的事務。

我們添加數據時啟動了一個事務,更新數據時,Spring判斷當前已經存在事務,所以就不再新建事務,而是加入當前事務。

但是當更新操作失敗時,需要對事務進行回滾,更新是沒問題的,正常回滾。

但是插入操作就不行了,當要提交插入操作的事務時,由于事務已經被回滾了,無法再次操作,Spring只好報錯來提示我們了。

如何處理呢?在更新操作上指明事務的傳播范圍就行。

@Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRES_NEW)
public void update(User user){
user.setPwd("666666");
int update = this.userMapper.updateById(user);
if (update > 0) {
throw new RuntimeException("測試更新數據回滾");
}
}

再測試一下,發現插入操作的事務可以正常提交了。

總結

事務是我們日常開發工作中無法避免的一個功能,深刻理解事務的運行機制,正確使用事務的聲明式操作,才能讓我們寫出更健壯的代碼。

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

2023-05-26 07:19:49

Spring聲明式事務

2023-09-14 15:44:46

分布式事務數據存儲

2022-12-06 10:39:43

Spring事務失效

2021-04-14 15:17:08

Transaction代碼語言

2024-03-26 12:08:53

分布式事務存儲

2024-06-13 08:04:23

2020-03-31 16:13:26

分布式事務方案TCC

2010-09-02 15:18:42

CSSASP.NET

2024-09-09 08:29:25

2020-12-18 10:13:19

晉升職級協議

2025-04-29 04:00:00

分布式事務事務消息

2019-07-25 15:32:35

分布式事務微服務系統架構

2025-02-28 09:47:36

2024-05-22 19:10:18

跨域Web開發

2010-01-05 10:57:30

2024-01-29 08:28:01

Spring事務失效

2021-07-06 13:32:34

零信任網絡安全網絡攻擊

2019-03-12 10:30:29

開源備份Borg Backup

2023-03-08 12:39:47

架構

2021-09-04 07:56:44

Spring事務失效
點贊
收藏

51CTO技術棧公眾號

日韩成人在线视频观看| 久久99蜜桃精品| 日韩精品视频三区| 亚洲欧美日韩国产| 偷拍自拍在线看| 久久精品道一区二区三区| 亚洲老司机av| 污污视频网站在线| 91资源在线观看| 欧美激情一区在线| 国产高清在线精品一区二区三区| 亚洲天堂男人av| 欧美激情偷拍自拍| 日韩av资源在线播放| 亚洲自拍第三页| 在线最新版中文在线| 亚洲人成网站色在线观看| 欧美日韩综合久久| www.久久久久久久久久| 日韩在线播放一区二区| 午夜精品久久久久久久男人的天堂| www久久久久久久| 黑人久久a级毛片免费观看| 欧美无乱码久久久免费午夜一区| 美女扒开大腿让男人桶| 日韩三级影院| 久久久久久影视| 国产精品一区二区三区免费| 亚洲字幕av一区二区三区四区| 国产日韩亚洲| 欧美精品videossex性护士| 最新日韩免费视频| 欧美午夜精品一区二区三区电影| 亚洲国产精品大全| 欧美午夜精品一区二区| 日韩免费大片| 精品视频一区二区三区免费| 亚洲自偷自拍熟女另类| 精品人人视频| 亚洲国产精品尤物yw在线观看| 天堂av免费看| 毛片在线看网站| 中文字幕av一区 二区| 欧美福利精品| 欧美视频综合| 91麻豆国产在线观看| 国产一区二区高清视频| 亚洲精品网站在线| 国产成人av福利| 亚洲一区二区三区成人在线视频精品 | 中文字幕日韩高清| 一区二区伦理片| 国产日产精品一区二区三区四区的观看方式 | 国产91精品青草社区| 国产无套在线观看| 亚洲人成人一区二区三区| 久久久人成影片一区二区三区观看| 欧美国产在线看| 国产综合精品一区| 欧美黄色小视频| 日韩成人在线免费视频| 中文国产一区| 国产99视频精品免视看7| 一级黄色av片| 久久精品久久综合| 91亚洲永久免费精品| 国产黄色av片| 91在线观看免费视频| 久久视频在线观看中文字幕| 九九热视频在线观看| 欧美激情综合五月色丁香| 性刺激综合网| 影音先锋中文在线视频| 亚洲国产一区二区a毛片| 欧美日韩一道本| 日韩av大片站长工具| 欧美色老头old∨ideo| 亚洲欧美日本一区二区三区| 日韩精品成人在线观看| 亚洲国产日韩欧美综合久久 | 国产日韩高清在线| 亚洲日本精品一区| 午夜小视频福利在线观看| 亚洲成人av一区| 日韩欧美xxxx| 国产精品一区三区在线观看| 欧美精品一区二区高清在线观看| 老司机福利av| 91tv官网精品成人亚洲| 国内精品一区二区三区四区| 亚洲婷婷久久综合| 国产馆精品极品| 欧美精品欧美精品系列c| 老司机精品免费视频| 国产精品嫩草在线观看| 精品成人在线观看| 国产欧美在线观看一区| 亚洲国产国产亚洲一二三| av日韩在线免费观看| 国产九色在线| 久久久精品国产sm调教| 国产chinasex对白videos麻豆| 久久精品99国产精品日本| 99中文字幕| 精品影院一区| 亚洲国产综合91精品麻豆| 91在线视频观看免费| 亚洲高清在线一区| 伊人久久免费视频| 免费一级特黄特色大片| 久久精品理论片| 欧美日韩一区二区视频在线| 成人在线视频亚洲| 在线观看一区日韩| 亚洲午夜久久久久久久久| 欧美h版在线| 欧美一级黑人aaaaaaa做受| h狠狠躁死你h高h| 中文字幕欧美国产| ww国产内射精品后入国产| 精品国产亚洲一区二区三区在线| 亚洲无亚洲人成网站77777| 久久艹精品视频| 激情欧美一区二区三区在线观看| 欧美在线一区二区三区四区| 成人超碰在线| 日韩午夜激情av| 四虎影视一区二区| 日韩av一区二区在线影视| 精品国产免费人成电影在线观... 精品国产免费久久久久久尖叫 | 一区二区三区伦理片| 在线一区欧美| 久久大片网站| 99re6在线精品视频免费播放| 欧美一区二视频| 日韩在线视频网址| 另类小说视频一区二区| 日韩精品国内| 欧美成人黑人| 亚洲美女在线看| 91在线看视频| av电影一区二区| 欧美日韩一道本| 日韩三级av| 91av视频在线| 欧美视频综合| 欧洲人成人精品| 国产三级在线观看完整版| 日本不卡123| 亚洲视频欧美在线| 婷婷激情成人| 久色乳综合思思在线视频| 国产理论视频在线观看| 亚洲蜜臀av乱码久久精品蜜桃| 亚洲美女爱爱视频| 中文字幕免费一区二区| 亚洲一区二区三区四区视频| 在线免费av导航| 精品免费日韩av| 日韩av电影网址| 91蝌蚪porny| 免费男同深夜夜行网站| 成人av动漫在线观看| 国产专区欧美专区| 青春草视频在线| 亚洲精品国产suv| 久久久久久亚洲av无码专区| 国产精品入口麻豆原神| 免费黄频在线观看| 亚洲全部视频| 亚洲第一在线综合在线| 激情五月综合婷婷| 国内精品在线一区| 国产黄在线播放| 3d成人h动漫网站入口| 欧美精品入口蜜桃| 久久久影视传媒| 91女神在线观看| 韩国亚洲精品| 日本电影一区二区三区| 国产精品色婷婷在线观看| 高清欧美一区二区三区| 国产中文字幕在线| 日韩欧美国产综合| 三级视频在线观看| 亚洲免费观看高清| 久久亚洲AV成人无码国产野外 | 天堂视频中文在线| 欧美日韩国产高清一区| 国产在线免费视频| 国产欧美日韩在线观看| 国产伦理在线观看| 免费精品视频在线| 成人区一区二区| 欧美极品中文字幕| 亚洲free嫩bbb| 欧美大片高清| 欧美日产国产成人免费图片| 你懂的视频在线| 日韩色视频在线观看| 日本中文字幕久久| 亚洲国产精品久久艾草纯爱| 秋霞网一区二区三区| 波多野结衣中文字幕一区二区三区| 亚洲成人福利在线观看| 夜夜精品视频| 91精品国产吴梦梦| 人人妻人人澡人人爽久久av| 色综合久久久久综合99| 欧美日韩免费做爰视频| 欧美极品另类videosde| 日本japanese极品少妇| 国产电影一区在线| 久久综合伊人77777麻豆最新章节| 禁久久精品乱码| 超碰免费在线公开| 国产成人精品999在线观看| 国产成人精品一区二区三区福利| 91福利精品在线观看| 91精品国产91久久久久福利| 色呦呦在线播放| 最近2019年手机中文字幕| 色网站在线免费观看| 亚洲国产成人91精品| a毛片在线免费观看| 欧美裸体一区二区三区| 制服丝袜在线一区| 色94色欧美sute亚洲线路一久 | 懂色中文一区二区三区在线视频| 亚洲伊人精品酒店| 国产精品久久一| 欧美黑人粗大| 国产福利视频一区| 91精品论坛| 欧美重口另类videos人妖| 九色porny丨入口在线| 亚洲91精品在线| www.综合网.com| 欧美激情久久久| xxxcom在线观看| 97国产精品免费视频| 国产传媒av在线| 97久久久久久| sm在线播放| 欧美亚洲成人精品| 涩涩视频在线播放| 热99久久精品| 国产精品字幕| 国产在线观看精品| www一区二区三区| 亚洲自拍另类欧美丝袜| 久久久91麻豆精品国产一区| 97夜夜澡人人双人人人喊| 欧美另类中文字幕| 国产精品裸体一区二区三区| 久久狠狠久久| 欧美一二三区| 99久久亚洲精品蜜臀| 中文字幕の友人北条麻妃| 国产精品www994| 国内性生活视频| 日本免费新一区视频| 在线免费看污网站| 成+人+亚洲+综合天堂| 国产在线观看无码免费视频| 久久久精品影视| 国产3级在线观看| 亚洲激情五月婷婷| 精品人妻一区二区色欲产成人| 91福利资源站| 国产成人精品亚洲精品色欲| 亚洲国产高清自拍| 精品av中文字幕在线毛片| 色av吧综合网| www.8ⅹ8ⅹ羞羞漫画在线看| 国产精品成人免费电影| 豆花视频一区| 精品久久久久久中文字幕动漫| 国内精品久久久久久久久电影网 | 国产精品大片| 黑森林福利视频导航| 国内成人精品2018免费看| 特级特黄刘亦菲aaa级| 国产日产欧产精品推荐色| 国产精品 欧美激情| 欧美日韩国产页| 6—12呦国产精品| 亚洲国产欧美在线成人app| 99视频在线观看地址| 欧美激情中文字幕乱码免费| 456亚洲精品成人影院| 91中文在线视频| 亚洲免费福利一区| 秋霞在线一区二区| 美女久久一区| 精品人妻人人做人人爽夜夜爽| 久久先锋资源网| 69av.com| 精品视频一区三区九区| 欧美熟妇另类久久久久久不卡 | 成人免费视频网站入口::| 日韩欧美在线视频| 精品国产99久久久久久宅男i| 亚洲人成网站在线播| 国产探花在线观看| 91麻豆国产精品| 啄木系列成人av电影| 青青在线视频免费观看| 奇米精品一区二区三区在线观看 | 亚洲人妖av一区二区| 中文字幕av影院| 精品久久久久久综合日本欧美| porn视频在线观看| 国内精品久久久久| 激情综合婷婷| 最新中文字幕久久| 免费人成精品欧美精品 | 亚洲欧美另类小说视频| 波多野结衣电车| 国产视频精品久久久| 77thz桃花论族在线观看| 91丝袜脚交足在线播放| 国产精品成人av| 91精品无人成人www| 久久精品亚洲乱码伦伦中文| 精品深夜av无码一区二区老年| 91精品国产综合久久久久久漫画| 成人性生交大片免费看午夜| 欧美在线视频免费播放| 女同久久另类99精品国产| 97碰在线视频| 国产不卡视频在线播放| 少妇影院在线观看| 日韩一区和二区| 国产人成网在线播放va免费| 成人妇女淫片aaaa视频| 日韩欧美一区二区三区免费看| 国产wwwxx| 26uuu亚洲综合色| www.中文字幕在线观看| 亚洲黄色av网站| 欧美男男tv网站在线播放| 国产欧美日韩一区| 亚洲乱码久久| 亚洲精品乱码久久久久久久| 精品人伦一区二区三区蜜桃网站 | 日韩中文字幕亚洲| 日韩国产大片| 亚洲五码在线观看视频| 国产精品99久久久久久有的能看| 手机在线免费看片| 日韩欧美高清一区| 密臀av在线| 精品视频高清无人区区二区三区| 国产情侣一区| 久久久久无码精品国产sm果冻| 欧美午夜一区二区三区免费大片| 97电影在线看视频| 91精品久久久久久蜜桃| 狠狠综合久久| 老司机福利av| 欧美日韩成人综合在线一区二区| 国产精品刘玥久久一区| 成人欧美一区二区三区视频| 99精品国产在热久久婷婷| 免费污网站在线观看| 欧美三级电影一区| 成人日日夜夜| 精品蜜桃传媒| 蜜臀av性久久久久蜜臀av麻豆| 国产老头老太做爰视频| 精品精品欲导航| av资源亚洲| 在线视频一区观看| www.亚洲激情.com| 一级一级黄色片| 九九精品在线播放| 亚洲黄页网站| xxxx在线免费观看| 亚洲国产精品久久不卡毛片| 国产黄色片在线观看| 亚洲在线免费视频| 久久久久一区| 麻豆视频在线免费看| 亚洲精品一区久久久久久| 欧美美女被草| 777精品久无码人妻蜜桃| 国产精品久久久久久久浪潮网站| 成人黄色免费视频| 国产精品日韩欧美大师| 黄色成人精品网站| 国产18无套直看片| 亚洲国产欧美日韩精品| 99精品女人在线观看免费视频 | 成人自拍视频在线| 欧美性受xxx黑人xyx性爽| 欧美劲爆第一页| 久久综合电影| 一级片视频免费看| 欧美精品一区二区三区蜜臀|