亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

事務注解(@Transactional)引起的數據覆蓋故障

發布時間:2020-08-11 08:23:07 來源:ITPUB博客 閱讀:226 作者:普通程序員 欄目:數據庫

最近組織團隊內技術培訓,劉聰為分享的一個跟事務和寫數據庫相關的case(bug)很有代表性。用事務,要小心!

一、故障現象

車輛交付履約流程上兩個節點(工程項目)A和B, A修改一條數據記錄item(工單),然后發消息給B,B也會對item進行修改。

故障現象,有時候(不是必現)感覺A沒有成功修改item這條數據,而日志顯示A修改成功了數據item!

看一下具體代碼實現。下圖是工程A代碼,3個紅框依次動作。

1、開啟事務

2、修改工單記錄item

3、向下游節點發送mq消息 

事務注解(@Transactional)引起的數據覆蓋故障

下圖是下游消費mq消息的節點B,紅框表示采用JPA技術修改數據記錄item

事務注解(@Transactional)引起的數據覆蓋故障

二、原因分析

這個過程總共經歷5個步驟,見下圖 

事務注解(@Transactional)引起的數據覆蓋故障

1、節點A開啟一個事務,修改數據表中某條數據item

2、A向B發送mq消息,再做些其他事情,提交事務

3、節點B,消費mq消息

4、節點B讀出數據item

5、節點B在內存中修改數據item某些字段,寫回數據庫

注意到第1、2步驟是在一個事務中。存在一種可能,B節點收到mq消息,執行第4步驟,讀取item數據后,步驟1、2的事務才完成提交。由于數據庫事務隔離級別,這種情況下,第4步驟讀到的數據并不是A節點在第1步寫的,已經讀到臟數據了。當第5步寫回數據的時候,就可能造成老數據覆蓋A寫的新數據

這里有兩個細分場景

1、第1步、第5步修改同一個字段。這種情況,第4步驟讀到臟數據 

事務注解(@Transactional)引起的數據覆蓋故障

2、第1步、第5步修改不同字段。第4步讀到col2字段的oldvalue,第5步目的是修改col3的值,但是采用jpa或者mybatis的一些默認寫法,會把col2的oldvalue更新回數據庫。

一般的ORMapping框架利用一個vo對象寫數據庫記錄,沒有修改的字段不會更新(代碼里并沒有改col2的值),但是第4步讀取數據后,第1步對數據item進行了修改。這樣默認的寫庫方法,會check記錄的變化,然后把col2字段的值更新。這樣就出現了舊值覆蓋新值的問題。 

事務注解(@Transactional)引起的數據覆蓋故障

三、解決辦法

1、考慮到實施成本,如果修改不同的字段,不存在競爭關系。只需要在第5步寫庫的環節指定更新字段就能快速解決這個問題。事實上,生產環境下也是選擇的這個方案臨時修復。

2、解決辦法1顯然不夠優秀。更好的做法,把第2步發mq消息從事務中拆出來,等第1步操作commit后在發mq消息。這個辦法涉及到一些邏輯的梳理(業務代碼里會有不少的if……else),代碼的改動。這樣處理仍然不夠完美,第1步執行完了,第2步失敗了怎么辦?在這里可能需要一些額外的代碼工作保證第2步執行成功。

3、如果業務壓力不大,也可以考慮從數據庫的事務隔離級別方面入手來解決這個問題。

4、業務上,第1步到第5步如果需要強一致,了解一下分布式事務

https://www.jianshu.com/p/16b1baf015e8

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

彰化县| 永善县| 霍林郭勒市| 会理县| 滨州市| 仲巴县| 喀什市| 赤峰市| 梨树县| 衡水市| 准格尔旗| 农安县| 读书| 伊金霍洛旗| 稷山县| 新营市| 南宁市| 河北省| 共和县| 揭阳市| 法库县| 芒康县| 宁都县| 西乌| 公主岭市| 德江县| 无极县| 商都县| 霞浦县| 隆回县| 辛集市| 怀柔区| 黄浦区| 桓台县| 于都县| 红安县| 宁国市| 双牌县| 滕州市| 都昌县| 瓦房店市|