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

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

Spring事務相關問題解決方案

瀏覽:133日期:2023-09-19 14:30:48

有些spring相關的知識點之前一直沒有仔細研究:比如spring的事務,并不是沒有使用,也曾經簡單的在某些需要事務處理的方法上通過增加事務注解來實現事務功能,僅僅是跟隨使用(甚至并未測試過事務的正確性),至于如何在項目中配置事務,如何才能將事務寫正確,事務的其它的一些原理性的東西從未花時間研究。最近同事正好拋出了一個問題,借此機會學習了一遍。

問題一:增加了readOnly=true的事務中包含寫操作,為什么線上運行這段代碼是正常的呢?

@Transactional(readOnly = true) public Integer getUID(String key, String type) { keyGeneratorDao.insert(key, type); keyGeneratorDao.update(key, type); return keyGeneratorDao.select(key, type); }

我為什么對這個問題感興趣?

不懂這個readOnly參數的含義,之前寫@Transactional的注解,那都是使用的默認值,不帶顯示參數。提出配置了readOnly參數后,理論上應該程序報錯而實際上沒有報錯,想搞清楚為什么。

開始寫單元測試:

在單元測試類中寫事務函數以及測試方法

@Autowired private IkeyGeneratorDao keyGeneratorDao; @Transactional(readOnly=true) public Integer getId(String key, String type){ return keyGeneratorDao.select(key, type); } @Transactional public Integer getUID(String key, String type) { keyGeneratorDao.insert(key, type); keyGeneratorDao.update(key, type); return this.getId(key,type); } @Test public void testCreateGuid(){ int guid=this.getUID('12345', 'jim'); System.out.println(guid); }

測試結果顯示正常,與上面提到的不允許進行寫操作的觀點相反,于是想起典型的事務生效問題。

挖的第一個坑:如果事務采用的是cglib動態代理,調用的方法與事務方法處在同一個類中事務不生效。

將兩個事務事務轉移到單獨的類中,然后測試,類代碼省略,只是將上面兩個標記了@Transactional的方法封裝在一個單獨的類中。

@Autowired private KeyGeneratorService keyService; @Test public void testCreateGuid2(){ int guid=this.keyService.getUID('12345', 'jim'); System.out.println(guid); }

測試結果顯示也是正常,于是想確認下事務到底是否生效,加入異常以測試數據是否回滾,修改代碼如下:

@Transactional public Integer getUID3(String key, String type) { keyGeneratorDao.insert(key, type); Integer.parseInt('aaa');//throw exception keyGeneratorDao.update(key, type);}

測試結果顯示事務回滾正常,可以排除事務環境配置問題。

挖的第二個坑:做測試一定要與原問題代碼盡量保持一致,否則會產生其它的不明原因影響判斷。通過對比原問題的代碼發現我寫的測試代碼與問題代碼有區別,readOnly是加在包含有寫操作的方法上,而我的是兩個方法,只有在讀的方法上增加了readOnly,于時再次修改代碼:

@Transactional(readOnly = true) public Integer getUID4(String key, String type) { keyGeneratorDao.insert(key, type); keyGeneratorDao.update(key, type); return keyGeneratorDao.select(key, type); }

測試結果顯示運行不正常,提示如下錯誤:Cause: java.sql.SQLException: Connection is read-only. Queries leading to data modification are not allowed,到這的確說明在在加了readOnly=true的事務內是不允許寫入操作的。為什么這段代碼在線上運行是成功的呢,于時查看前端的調用,發現前端調用的并不是直接標識了Transactional的方法,而是根據不同的具體業務重新包裝的方法,比如我們需要生成訂單的編號,前端只調用genOrderCode而不調用getUID。

非事務方法在內部調用了本類事務方法,然后非事務方法被外部調用ServicegenOrderCode,是一個非事務方法,內部調用了getUIDgetUID,是一個事務方法

@Autowired private IkeyGeneratorDao keyGeneratorDao; @Transactional(readOnly = true) public Integer getUID(String key, String type) { keyGeneratorDao.insert(key, type); keyGeneratorDao.update(key, type); return keyGeneratorDao.select(key, type); } public String genOrderCode(Date orderDate) { SimpleDateFormat df = new SimpleDateFormat('yyMMddHH'); String ticketDate = df.format(orderDate); Integer uid = getUID(ticketDate, ORDER_CODE);return ticketDate + genRandom2(uid.toString(), 3, 3) ; }

Test,外部類調用非事務方法

@Test public void testCreateGuid3(){ String guid=this.keyService.genOrderCode(new Date()); System.out.println(guid); }

測試結果居然是正常的,這與線上運行的結果相同,后面經同事提醒,這又是一個不正確使用事務的案例。

挖的第三個坑:當調用一個類的非事務方法且這個非事務方法內部調用了本類自身的事務方法,那么事務也不會生效。

問題二:下面的代碼可以實現事務回滾嗎?

Service

genOrderCode方法調用 getUID2兩個方法都是具備相同的事務參數 getUID2拋出異常 genOrderCode捕獲這個異常

@Transactional public Integer getUID2(String key, String type) { keyGeneratorDao.insert(key, type); Integer.parseInt('aaa');//throw exception keyGeneratorDao.update(key, type); return keyGeneratorDao.select(key, type); } @Transactional public String genOrderCode(Date orderDate) { try{ SimpleDateFormat df = new SimpleDateFormat('yyMMddHH'); String ticketDate = df.format(orderDate); Integer uid = getUID2(ticketDate, ORDER_CODE); return ticketDate + genRandom2(uid.toString(), 3, 3) ; }catch(Exception ex){ System.out.println(ex); } return null; }

Test

@Test public void testCreateGuid3(){ String guid=this.keyService.genOrderCode(new Date()); System.out.println(guid); }

執行測試代碼,發現可以成功提交,但數據是不完整的,因為更新操作沒有完成。為什么會是這樣的呢?因為默認的Propagation.REQUIRED指明多個操作處于一個事務中,由于genOrderCode有異常處理,所以即使getUID2中發生異常,系統也會認定提交是合法的,因此會出現插入操作正常更新不正常但事務正常提交并不回滾的情況。如果顯示指定Propagation.REQUIRES_NEW呢?

@Transactional(propagation=Propagation.REQUIRES_NEW) public Integer getUID2(String key, String type) { keyGeneratorDao.insert(key, type); Integer.parseInt('aaa');//throw exception keyGeneratorDao.update(key, type); return keyGeneratorDao.select(key, type); }

再執行相同的測試,數據正常回滾,這里提供兩張圖,可以看的清楚些(因為常用的就這兩種,其它的有興趣可以多多研究)

REQUIRED

Spring事務相關問題解決方案

REQUIRES_NEW

Spring事務相關問題解決方案

通過事務的兩個小問題,總結出解決問題的一些小技巧或者叫經驗:發現問題之后,不要局限于某個點,最好根據上下文來結合分析,比如問題一的readonly可寫入,單看那段代碼很難找出合理的解釋,只有結合前后端調用才能找出根本原因。寫單元測試盡量寫相同的代碼,否則有可能會出現一些干擾項影響判斷。學習呢,有時間盡量學的全點,比如@Transactional這個注解,除了readOnly還有Propagation等等。

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持好吧啦網。

標簽: Spring
相關文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
国产精品三p一区二区| 午夜一区在线| 日韩欧美另类中文字幕| 亚洲一区黄色| 视频一区欧美精品| 亚洲aa在线| 日本一区二区中文字幕| 日韩高清二区| 国产精品视频一区二区三区四蜜臂 | 蜜臀91精品一区二区三区| 伊人久久婷婷| 久热re这里精品视频在线6| 伊人国产精品| 日本综合精品一区| 奇米777国产一区国产二区| 久久狠狠久久| 国产成人免费视频网站视频社区| 久久字幕精品一区| 午夜精品成人av| 亚洲成人三区| 伊人精品久久| 国产精品国产一区| 免费在线成人网| 色婷婷色综合| 视频一区欧美精品| 欧美91视频| 亚洲青青久久| 麻豆高清免费国产一区| 97精品国产| 婷婷激情图片久久| 亚洲精品九九| 国产精品99久久免费| 91欧美日韩| 黄色在线一区| 7m精品国产导航在线| 欧美私人啪啪vps| 欧美好骚综合网| 丝袜美腿亚洲色图| 亚洲a级精品| 国产精品国产三级国产在线观看| av一区二区高清| 午夜精品影视国产一区在线麻豆| 欧美视频一区| 久久国产亚洲| 午夜电影一区| 日韩大片在线播放| 自拍自偷一区二区三区| 欧美国产专区| 亚洲先锋成人| 日韩欧美中文在线观看| 久久精品免视看国产成人| 日韩电影免费在线观看| 中文字幕亚洲影视| 精品一区二区男人吃奶 | 久久精品网址| 欧美日韩国产探花| 国产亚洲精品精品国产亚洲综合| 精品国产鲁一鲁****| 日韩国产在线一| 国产亚洲精品美女久久| 视频一区欧美日韩| 黑森林国产精品av| 日本午夜精品一区二区三区电影| 国内亚洲精品| 国产精品成人一区二区不卡| 人人爱人人干婷婷丁香亚洲| 免费欧美日韩| 一区三区视频| 国产综合婷婷| 日韩精品欧美| 高清av不卡| 国产一区二区三区亚洲| 国产乱码精品一区二区亚洲| 亚洲精品少妇| 中文字幕一区二区av| 欧美一级专区| 激情久久婷婷| 久久aⅴ国产紧身牛仔裤| 亚洲精品看片| 91精品99| 久久蜜桃资源一区二区老牛| 久久精品色播| 国产麻豆一区二区三区精品视频| 亚洲一区二区三区高清| 日韩中文影院| 精品一区二区三区中文字幕视频| 亚洲bt欧美bt精品777| 伊人久久亚洲影院| 97人人精品| 国产激情综合| 青青草精品视频| 天堂成人国产精品一区| 国产精品久久久久久久久久10秀| 日韩欧美久久| 丝袜美腿成人在线| 蜜桃国内精品久久久久软件9| 麻豆国产精品777777在线| 日本少妇一区二区| 亚洲理论在线| 中文字幕亚洲在线观看| 亚洲一区二区免费看| 91九色精品国产一区二区| 久久精品亚洲欧美日韩精品中文字幕| 国产aⅴ精品一区二区四区| 国产精品对白| 国产欧美日韩亚洲一区二区三区| 亚洲一区二区三区无吗| 国产精品99一区二区| 日韩啪啪电影网| 中文字幕在线免费观看视频| 美女视频黄久久| 麻豆精品视频在线| 国产精品xxx在线观看| 国产精品色在线网站| 国产欧美91| 国产日韩欧美三级| 国产日韩免费| 国产精品sss在线观看av| 国产精品伦一区二区| 国产午夜精品一区在线观看| 欧美综合精品| 国产毛片一区二区三区| 欧美影院视频| 麻豆精品视频在线观看视频| 久久99高清| 成人精品久久| 欧美黄色网页| 成人羞羞在线观看网站| 久久久精品日韩| re久久精品视频| 亚洲一区网站| 美女国产精品| 日本不卡视频在线| 国产日韩欧美一区| 高清日韩欧美| 亚洲精品一区三区三区在线观看| 久久婷婷久久| 影音先锋国产精品| 蜜臀久久99精品久久久画质超高清| 免费在线观看一区二区三区| 亚洲日本久久| 国产激情综合| 国产 日韩 欧美一区| 欧美va天堂在线| 男女激情视频一区| 国产精区一区二区| 久久精品天堂| 亚洲福利久久| 午夜在线视频一区二区区别| 日本亚洲欧洲无免费码在线| 国产精品欧美三级在线观看| 国产一区福利| 亚洲二区免费| 日韩综合一区二区| 国产黄色精品| 91精品一区二区三区综合在线爱 | 樱桃视频成人在线观看| 亚洲经典在线| 日本成人一区二区| 久久久久久色| 成人在线观看免费视频| 日韩精品一区二区三区免费观看| 夜夜嗨一区二区| 久久精品xxxxx| 天堂а√在线最新版中文在线| 一区二区亚洲精品| 日本电影久久久| 国产精品精品| 蜜桃一区二区三区在线观看| 久久精品色播| 日韩视频免费| 国产精品视频一区二区三区综合| 激情国产在线| 天使萌一区二区三区免费观看| 国产欧美亚洲一区| 久久国产小视频| 国产亚洲观看| 亚洲先锋成人| 国产精品资源| 今天的高清视频免费播放成人| 奇米亚洲欧美| 啪啪国产精品| 日本精品一区二区三区在线观看视频| 国产精品xvideos88| 欧美精品黄色| 久久尤物视频| 欧美专区18| 中文字幕人成乱码在线观看| 中文字幕亚洲影视| 日韩一区二区在线免费| 日本不卡视频在线观看| 久久精品国内一区二区三区水蜜桃| 日韩精品一区二区三区免费视频| 亲子伦视频一区二区三区| 日韩av不卡在线观看| 九一国产精品| 国产精品麻豆成人av电影艾秋| 亚洲主播在线| 日韩国产在线| 国产精品亚洲一区二区在线观看|