使用的是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...