並發修改同一條數據場景,比如:用戶同時打開多個充值窗口同時點充值、用戶同時打開多個商品頁面同時點購買、等
此時會產生多個update同一個用戶余額,如何保證並發情況下正確修改數據。
1.業務處理代碼加鎖:
這樣就一次只能處理一個請求,保證每一次update都是對的,但是犧牲了並發性能優點。
如果有100個用戶同時要修改自己的余額,那就只能排隊慢慢等,一個一個修改,越靠后的用戶等待時間越長。
2.在表結構中再加一個時間戳字段,用來標識余額上一次的修改時間:
業務代碼中先根據主鍵把余額和時間戳查出來
select 余額, 時間戳 from 表 where 主鍵=$主鍵
再去update,update的時候要同時更新時間戳,並且where條件加上時間戳判斷
update 表 set 余額 = 計算之后的余額, 時間戳 = 當前時間戳 where 主鍵 = $主鍵 and 時間戳 =上面查出來的時間戳
這樣就能保證只有一個update執行成功,然后業務代碼中也不用加鎖,只要加上重試機制就可以了,判斷update返回值如果是0就重新select再update。
如果有100個用戶同時要修改自己的余額,那就只要出現這種同時多次修改自己數據的用戶等待重試的時間就行了,其他用戶都能並發執行。
備注:也可以使用數據庫行級鎖,但是不同的數據庫鎖的語法和使用方式可能不一樣,sql語句都要根據使用的數據庫不同定制化寫,
這樣如果系統里使用多種數據庫,或者以后切換數據庫就會很麻煩,第2種方式就是為了解決這個問題而升級的方案。