日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

您的位置:首頁技術文章
文章詳情頁

spring 中事務注解@Transactional與trycatch的使用

瀏覽:62日期:2023-07-08 11:26:56
spring事務注解@Transactional與trycatch

在項目中 @service層中 我們會經常在做一些增刪改操作的方法上看到 spring 的事務注解 @transaction 已知@transaction 是讓spring 幫我們實現(xiàn)事務的控制。

但是在項目中會經常看到 有的方法中 會存在trycatch塊包括的方法上注解著@transaction

eg:

@Override @Transactional public Json addOrder(TOrderAddReq tOrderAddReq) { try{ //增刪改方法} catch (Exception e) { ..... e.printStackTrace();}//}return json; }

上述的方法執(zhí)行后可以看到事務并沒有執(zhí)行,接下來再看一個例子eg:

@Override @Transactional public Json addOrder(TOrderAddReq tOrderAddReq) { try{ //增刪改方法} catch (Exception e) { // 手動硬編碼開啟spring事務管理 TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); e.printStackTrace();}//}return json; }

上述方法執(zhí)行后我們可以看到事務最后執(zhí)行了,但實際上 事務 執(zhí)行只是因為手動硬編碼開啟spring事務管理起了作用 而方法上的注解并沒有起作用

接下來再看一個例子eg

@Override @Transactional public Json addOrder(TOrderAddReq tOrderAddReq) { try{ //增刪改方法} catch (Exception e) { throw new RuntimeException(); }//}return json; }

上述方法執(zhí)行后我們可以看到事務是執(zhí)行了的,但這里有個小細節(jié):@Transactional不做任何配置 默認是對拋出的unchecked異常回滾,checked異常不會回滾,為了讓所有異常都會讓事務啟動可以將 @Transactional配置為 @Transactional(rollbackFor = Exception.class)

解釋:

spring的事務邊界是在調用業(yè)務方法之前開始的,業(yè)務方法執(zhí)行完畢之后來執(zhí)行commit or rollback(spring默認取決于是否拋出runtime異常).

如果拋出runtime exception 并在你的業(yè)務方法中沒有catch到的話,事務會回滾。

一般不需要在業(yè)務方法中catch異常,如果非要catch,在做完你想做的工作后(比如關閉文件等)一定要拋出runtime exception,否則spring會將你的操作commit,這樣就會產生臟數(shù)據(jù).所以你的catch代碼是畫蛇添足。

@Transactional回滾問題(try catch、嵌套)

Spring 事務注解 @Transactional 本來可以保證原子性,如果事務內有報錯的話,整個事務可以保證回滾,但是加上try catch或者事務嵌套,可能會導致事務回滾失敗。測試一波。

準備

建兩張表,模擬兩個數(shù)據(jù)操作

CREATE TABLE `user` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(20) DEFAULT NULL, `age` smallint(3) DEFAULT NULL, PRIMARY KEY (`id`)) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;CREATE TABLE `role` ( `id` int(11) NOT NULL AUTO_INCREMENT, `role_name` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL, PRIMARY KEY (`id`)) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;測試

根據(jù)排列組合原理,我們進行四種測試:1、無try catch、無嵌套;2、有try catch、無嵌套;3、無try catch、有嵌套;4、都有。

最簡單測試

如果我們單純@Transactional,事務可以正常回滾嗎?

@GetMapping('/saveNormal0') @Transactional public void saveNormal0() throws Exception {int age = random.nextInt(100);User user = new User().setAge(age).setName('name:'+age);userService.save(user);throw new RuntimeException(); }

如果事務內報了RuntimeException錯誤,事務可以回滾。

@GetMapping('/saveNormal0') @Transactional public void saveNormal0() throws Exception {int age = random.nextInt(100);User user = new User().setAge(age).setName('name:'+age);userService.save(user);throw new Exception(); }

如果事務內報了Exception錯誤(非RuntimeException錯誤),事務不可以回滾。

@GetMapping('/saveNormal0') @Transactional( rollbackFor = Exception.class) public void saveNormal0() throws Exception {int age = random.nextInt(100);User user = new User().setAge(age).setName('name:'+age);userService.save(user);throw new Exception(); }

如果是Exception錯誤(非RuntimeException),加上 rollbackFor = Exception.class 參數(shù)也可以實現(xiàn)回滾。

結論一:對于@Transactional可以保證RuntimeException錯誤的回滾,如果想保證非RuntimeException錯誤的回滾,需要加上rollbackFor = Exception.class 參數(shù)。

try catch 影響

經過博主多種情況測試,發(fā)現(xiàn)try catch對回滾這個事本身沒有什么影響,結論一照樣成立。try catch只是對異常是否可以被@Transactional 感知 到有影響。如果錯誤拋到切面可以感知到的地步,那就可以起作用。

@GetMapping('/saveTryCatch') @Transactional( rollbackFor = Exception.class) public void saveTryCatch() throws Exception{try{ int age = random.nextInt(100); User user = new User().setAge(age).setName('name:'+age); userService.save(user); throw new Exception();}catch (Exception e){ throw e;} }

比如上面一段代碼就回滾了。

@GetMapping('/saveTryCatch') @Transactional( rollbackFor = Exception.class) public void saveTryCatch() throws Exception{try{ int age = random.nextInt(100); User user = new User().setAge(age).setName('name:'+age); userService.save(user); throw new Exception();}catch (Exception e){} }

然而,將catch中的錯誤不繼續(xù)網上拋,切面無法感知到錯誤,無法進行處理,那么事務就無法回滾了。

結論二:try catch只是對異常是否可以被@Transactional 感知 到有影響。如果錯誤拋到切面可以感知到的地步,那就可以起作用。

事務嵌套 影響

首先經過實驗,結論一仍然成立,即,當不加上rollbackFor = Exception.class 的時候,無論內外報RuntimeException,都會回滾;無論內外報 非RuntimeException 錯誤,都不會回滾。如果加上rollbackFor = Exception.class,無論內外怎么報錯,都會回滾。這些代碼就不給出了。接下來,試下下面兩種情況:

@GetMapping('/out') @Transactional( rollbackFor = Exception.class) public void out() throws Exception{innerService.inner();int age = random.nextInt(100);User user = new User().setAge(age).setName('name:' + age);userService.save(user);throw new Exception(); } @Transactional public void inner() throws Exception{Role role = new Role();role.setRoleName('roleName:'+new Random().nextInt(100));roleService.save(role);//throw new Exception(); }

情況一,外面事務加上rollbackFor = Exception.class,里面事務不加,測試內外分別報錯的情況(為了簡化代碼量,只給出了外面報錯的代碼),都可以回滾。因為,無論如何,錯誤都拋給了外面那個事務進行處理,而外面那個加上了rollbackFor = Exception.class,具備處理非RuntimeException錯誤的能力,所以都可以讓事務進行正常回滾。

下面看情況二,里面的事務加上rollbackFor = Exception.class,外面不加,外面報錯。

@GetMapping('/out') @Transactional public void out() throws Exception{innerService.inner();int age = random.nextInt(100);User user = new User().setAge(age).setName('name:' + age);userService.save(user);throw new Exception(); }@Transactional( rollbackFor = Exception.class) public void inner() throws Exception{Role role = new Role();role.setRoleName('roleName:'+new Random().nextInt(100));roleService.save(role); }

事務都無法回滾,這是我們有個疑問,里面的事務明明有很強的處理能力啊,為什么和外面一起回滾失敗呢,別著急,等等聊這個。

然后試下里面報錯:

@GetMapping('/out') @Transactional public void out() throws Exception{innerService.inner();int age = random.nextInt(100);User user = new User().setAge(age).setName('name:' + age);userService.save(user); } @Transactional( rollbackFor = Exception.class) public void inner() throws Exception{Role role = new Role();role.setRoleName('roleName:'+new Random().nextInt(100));roleService.save(role);throw new Exception(); }

咦,這回都進行了正常的回滾。我的天,這回外面沒有處理能力,為什么接受里面拋出來的錯誤,也進行了回滾!!!看上去,就好像里外事務總是同生共死的對不對?原來,@Transactional還有個參數(shù),看下源碼,這個注解還有默認值:

Propagation propagation() default Propagation.REQUIRED;

REQUIRED的意思是說,事務嵌套的時候,如果發(fā)現(xiàn)已經有事務存在了,就加入這個事務,而不是新建一個事務,所以根本就不存在兩個事務,一直只有一個!至于,此參數(shù)其他值,本文不進行測試。回到上面的問題,當外面報錯的時候,此時查看事務,沒有增加rollbackFor = Exception.class參數(shù),即沒有處理非RuntimeException能力,所以代碼走完,貌似“兩個事務”,都回滾失敗了。當里面報錯的時候,事務已經添加上了處理非RuntimeException能力,所以,代碼走完就回滾成功了。

結論三:由于REQUIRED屬性,“兩個事務”其實是一個事務,處理能力看報錯時刻,是否添加了處理非RuntimeException的能力。

try catch和事務嵌套 共同影響

在結論一二三成立的條件下,探索共同影響的問題就簡單多了,由于情況太多,就不進行過多的代碼展示了。

結論

結論一:

對于@Transactional可以保證RuntimeException錯誤的回滾,如果想保證非RuntimeException錯誤的回滾,需要加上rollbackFor = Exception.class 參數(shù)。

結論二:

try catch只是對異常是否可以被@Transactional 感知 到有影響。如果錯誤拋到切面可以感知到的地步,那就可以起作用。

結論三:

由于REQUIRED屬性,“兩個事務”其實是一個事務,處理能力看報錯時刻,是否添加了處理非RuntimeException的能力。

以上為個人經驗,希望能給大家一個參考,也希望大家多多支持好吧啦網。

標簽: Spring
相關文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
亚洲资源网站| 国产精品av久久久久久麻豆网| 午夜电影亚洲| 91精品一区二区三区综合在线爱 | 久久在线免费| 午夜免费一区| 午夜欧美精品久久久久久久| 女人av一区| 巨乳诱惑日韩免费av| 亚洲精品无播放器在线播放| 日韩在线成人| 国产福利一区二区精品秒拍| sm久久捆绑调教精品一区| 日韩专区精品| 99国产精品自拍| 日韩三级精品| 国产免费久久| 国产一区二区三区不卡视频网站| 国产日产精品一区二区三区四区的观看方式 | 热久久免费视频| 日韩黄色在线观看| 国产精东传媒成人av电影| 精品久久久网| 久久美女性网| 男人操女人的视频在线观看欧美| 亚洲精品黄色| 久久精品伊人| 日韩精品永久网址| 亚洲激情五月| 免费观看日韩电影| 日韩国产91| sm久久捆绑调教精品一区| 激情婷婷欧美| 日韩欧美久久| 精精国产xxxx视频在线播放| 亚洲日本欧美| 1000部精品久久久久久久久| 国精品一区二区三区| 99久久婷婷| 青草国产精品久久久久久| 欧美日中文字幕| 蜜桃国内精品久久久久软件9| 精品一区二区三区在线观看视频 | 亚洲婷婷在线| 成人污污视频| 成人在线视频区| 在线日韩中文| 日韩av一区二区在线影视| 桃色一区二区| 亚州欧美在线| 国产精品成人国产| 亚洲综合精品四区| 国产精品jk白丝蜜臀av小说| 欧美日韩国产传媒| 国产欧美欧美| 国产精品成人**免费视频| 99国产精品99久久久久久粉嫩| 黄色不卡一区| 精品一区二区三区的国产在线观看| 精品在线99| 精精国产xxxx视频在线野外| 国产精品v亚洲精品v日韩精品| 免费日韩av片| 久久精品福利| 99日韩精品| 国产精品亚洲综合色区韩国| 久久久久亚洲| 国产免费久久| 巨乳诱惑日韩免费av| 国内精品亚洲| 亚洲欧美网站在线观看| 精品视频久久| 亚洲精品高潮| 激情婷婷亚洲| 国产不卡av一区二区| 91精品国产经典在线观看| av一区二区高清| 成人国产精选| 国产欧美激情| 深夜福利一区| 成人av二区| 中文字幕人成乱码在线观看| 欧美欧美黄在线二区| 模特精品在线| 亚洲欧美伊人| 国产精品xx| 欧美久久精品| 视频一区二区中文字幕| 欧美一区二区三区高清视频| 国产一区二区三区天码| 欧美一级久久| 一区二区日韩免费看| 亚洲精品va| 久久国产免费| 国产 日韩 欧美一区| 日本久久黄色| 丁香婷婷久久| 欧美精品不卡| 91精品视频一区二区| 亚洲美女91| 综合激情视频| 亚洲午夜免费| 国产精品腿扒开做爽爽爽挤奶网站| 日韩精品中文字幕第1页| 精品国产a一区二区三区v免费| 日韩avvvv在线播放| 日韩在线观看一区二区三区| 中文精品电影| 婷婷久久免费视频| 天堂精品久久久久| 中文字幕亚洲精品乱码| 亚洲一区有码| 亚洲+小说+欧美+激情+另类| 亚洲性视频在线| 日本一不卡视频| 日韩欧美精品一区二区综合视频| 蜜臀久久99精品久久久画质超高清 | 久久国产主播| 韩国三级一区| 电影91久久久| 国产v日韩v欧美v| 精品国产精品久久一区免费式| 国产精品美女久久久久久不卡| 国产色99精品9i| 国产精品久av福利在线观看| 国产欧美欧美| 久久久久九九精品影院| 精品国产一区二区三区2021| 久久狠狠久久| 美女精品久久| 色爱综合网欧美| 亚洲h色精品| 欧美日韩国产综合网| 日韩一级网站| 亚洲69av| 久久久久九九精品影院| av资源新版天堂在线| 欧美成人基地| 99国产精品自拍| 日韩黄色在线观看| 麻豆视频久久| 色婷婷精品视频| 噜噜噜躁狠狠躁狠狠精品视频| 日韩精品一级二级 | 红桃视频国产一区| 亚洲一区二区小说| 国产三级一区| 岛国av在线播放| 一区久久精品| 亚洲狼人精品一区二区三区| 欧美一区精品| 水蜜桃精品av一区二区| 亚洲午夜精品久久久久久app| 久久www成人_看片免费不卡| 日韩国产精品久久久久久亚洲| 欧美一区二区三区久久| 国产一区二区三区天码| 国产一区二区中文| 少妇精品在线| 久久久久久夜| 石原莉奈在线亚洲二区| 欧美日韩中出| 日韩欧美精品综合| 久久xxxx| 国产精品主播| 色爱av综合网| 亚洲欧美专区| 国产精品99一区二区三区| 欧美日韩高清| 久久国产乱子精品免费女| 精品国产亚洲日本| 伊人影院久久| 国产精品hd| 亚洲二区三区不卡| 国产精品欧美大片| 亚洲午夜91| 国产日产精品_国产精品毛片 | 日韩毛片网站| 日韩在线视频精品| 日韩欧美中文字幕电影| 97se综合| 日韩福利视频导航| 91精品综合| 国产精品久久久久久模特| 欧美一区二区三区激情视频 | 日本免费一区二区视频| 亚洲综合电影| 日本一区二区三区中文字幕| 色黄视频在线观看| 在线观看视频免费一区二区三区| 久久亚洲国产精品尤物| 国产亚洲一级| 中文字幕人成乱码在线观看| 亚洲91网站| 亚洲午夜电影| 久久亚洲黄色| 日韩欧美高清一区二区三区| 99免费精品| 国产精品亚洲一区二区在线观看| 婷婷综合亚洲|