記錄一次併發導致的錢包金額不一致,後者覆蓋前者

2021-08-20 20:21:28 字數 842 閱讀 2490

使用的是hibernate  jpa, mysql 5.6

假設    

執行緒t1讀取錢包金額為100

同時執行緒t2也讀取錢包金額為100

t1  增加錢包金額10,  錢包金額=110;

t2  增加錢包金額5 ,   錢包金額=105;

此時 t1  update    資料庫記錄為110;

t2隨後 update     此時會將t1修改的資料給覆蓋 為 105;

問題就出現了,後者更新覆蓋了前者的更新,理論應該是 後者(t2) 增加5 ,應該在前者(t1) 更新資料之後的結果上增加

解決過程:

使用樂觀鎖:在錢包實體 增加

@version

private int version;

字段 記錄當前資料版本號,每次更新錢包時 同時自增當前version欄位,後者更新時會比較當version版本是否一致,如果一致則更新成功,如果不一致將丟擲異常 這時我們要手動捕獲異常org.hibernate.staleobjectstateexception  再cath 裡將需要處理的過程重新處理一遍即可解決。

附上別的解決方法:

對於對財務系統等對資料可靠性,正確性高的系統,可以使用 更新 金額錢 通過當前執行緒對 錢包表(或其它)

進行表鎖:lock tables 表名 write;

注意:此時當前鎖住的表只有當前執行緒可以執行讀取、更新,別的執行緒過來讀取、更新 只能等待當前執行緒釋放表鎖,

此時就可以在當前執行緒內執行完成更新錢包記錄然後釋放鎖

釋放表鎖:unlock tables;

釋放鎖後等待執行緒就會執行。

因為是表鎖,所以效能上肯定會有一定的影響,按需選擇

記錄一次碰到的併發安全問題

還未進行生產測試,若存在問題請指出。兩個執行緒a,b。共享乙個arraylist。執行緒a接收資料,add到arraylist,根據列表中的記錄條數決定是否傳送到中間儲存件。執行緒b定時執行傳送。arraylistbuffer private final static int count 100 a...

偶爾一次的記錄

here to my github 我做了什麼?網頁的非同步載入導致的空資料爬取 解決方法 查詢目標json資料的request url作為處理物件 爬取的資料出現亂碼 解決方法 網上的 encoding格式宣告為 utf 8 我遇到的另乙個問題 宣告格式後返回資料仍是亂碼,且中文輸出正常,懷疑是r...

記一次Redis bitmap導致的miss問題

redis bitmaps 基礎概念 redis 記憶體淘汰機制 大致需求 指令碼批量匯入使用者資料到redis中,使用bitmap標記使用者是否在匯入的白名單中。使用者量級 億。key使用了分片處理,把key分成了10w個,每個key占用 1億 10w 1000 個bit。理想是key1用於標記u...