并發(fā)扣費(fèi)和充值操作沖突的解決方案
當(dāng)賬戶存在并發(fā)扣費(fèi)和充值操作時(shí),金額可能會(huì)出現(xiàn)不一致的情況。為了解決此問(wèn)題,需要采取措施防止并發(fā)沖突。
根據(jù)不同的場(chǎng)景,有以下兩種常見(jiàn)解決方案:
保證操作原子性
- 悲觀鎖:使用用戶 id 作為鎖標(biāo)識(shí)。變更賬戶余額時(shí)嘗試獲得鎖。獲得鎖成功則繼續(xù)操作,否則阻塞。
- 隊(duì)列:將扣費(fèi)和充值操作放入 fifo 隊(duì)列中。消費(fèi)者依次取出隊(duì)列中的操作并執(zhí)行,保證操作同步進(jìn)行。
提高性能
- 樂(lè)觀鎖:獲取賬戶余額時(shí)同時(shí)獲得數(shù)據(jù)版本。變更余額時(shí)比較版本。版本一致表示數(shù)據(jù)未被更新,繼續(xù)操作。否則,操作失敗。
sql 示例
使用樂(lè)觀鎖時(shí)的 sql 語(yǔ)句:
update account_balance set balance = balance + :changeNum, version = version + 1 where user_id = :userId and version = :version
登錄后復(fù)制
其中,:changenum 為變更金額,:userid 為用戶 id,:version 為數(shù)據(jù)版本。
如果 sql 響應(yīng)行數(shù)為 1,表示更新成功;如果為 0,表示更新失敗(數(shù)據(jù)已被更新)。