樂觀鎖限額控制

2021-08-03 11:32:34 字數 2118 閱讀 5471

為了解決併發下的商戶限額問題,由於服務是分布式的方式部署在多台伺服器上的,故選擇樂觀鎖為解決方案。

即使用資料版本(version)記錄機制實現,這是樂觀鎖最常用的一種實現方式。何謂資料版本?即為資料增加乙個版本標識,一般是通過為

資料庫表增加乙個數字型別的 「version」 欄位來實現。當讀取資料時,將version欄位的值一同讀出,資料每更新一次,對此version值加一。當我們提交更新的時候,判斷

資料庫表對應記錄的當前版本資訊與第一次取出來的version值進行比對,如果資料庫表當前版本號與第一次取出來的version值相等,則予以更新,否則認為是過期資料。

在這裡是直接進行限額更新然後進行邏輯操作,也就是在限額累加之後實際上並沒有實際扣款,所以如果之後的交易扣款失敗,要回滾限額。

merchant merchant = order.getmerchant();

map paramap = new hashmap();

int updatesecflag = 0;//更新限額成功標誌

int i =0;//計數器

paramap.put(dict.merchantid, merchant.getid());

doif (!constants.mertransctrl_ok.equals(mtc.getstatus()))

// 訂單金額大於商戶單筆金額

if (order.getamount().compareto(mtc.getpertranslimit()) > 0)

date today = (date) ctx.getdata(dict.pptransdate);

dateformat df = miscutil.getdateformat("yyyymmdd");

string todaystr = df.format(today);

if (mtc.getdayamtdate() != null && todaystr.equals(df.format(mtc.getdayamtdate())))

//更新當日限額

mtc.setdayamt(mtc.getdayamt().add(order.getamount()));

updatesecflag = this.getsqlmap().update("pp.core.updatemertransctrl", mtc);

} else

//更新當日限額和交易日期

mtc.setdayamt(order.getamount());

mtc.setdayamtdate(today);

mtc.setversion(1);

updatesecflag = this.getsqlmap().update("pp.core.updatemertransctrlforonece", mtc);

}i++;

}while(updatesecflag != 1 && i<100);

如果是當日的第一筆交易,更新累計金額為當筆實際支付金額並將version設定為「1」。

日間情況查表sql

update 

ft_mer_transctrl

setmertc_pertranslimit=#pertranslimit#

mertc_perdaylimit=#perdaylimit#

mertc_dayamt=#dayamt#

mertc_dayamtdate=#dayamtdate#

mertc_status=#status#

mertc_closedate=#closedate#

channel_modifydate=#modifydate#

mertc_openuser=#openuser#

channel_closeuser=#closeuser#

version=#version#+1

where

mer_id = #merchantid#

andversion = #version#

如果是過期資料查表失敗則拿到當前版本重新操作。認為100次應該是足夠滿足我們的業務要求的,故在此設定了乙個迴圈限制。

如果後續轉賬交易失敗,要回滾已累加的限額。過程和之前類似。

Redis 樂觀鎖控制事務

redis對事務的支援比較簡單。redis只能保證乙個客戶端發起的事務命令可以執行,中間不會插入其他事務。因為redis是單執行緒的,所以做到上面這點很容易。一般redis接受到客戶端的命令後會立即執行,但是如果客戶端發起multi命令,redis不會立即執行,而是讓當前連線進入事務上下文,把命令放...

Redis樂觀鎖控制事務

redis對事務的支援比較簡單。redis只能保證乙個客戶端發起的事務命令可以執行,中間不會插入其他事務。但 redis集群不支援事務。因為redis是單執行緒的,所以做到上面這點很容易。一般redis接受到客戶端的命令後會立即執行,但是如果客戶端發起multi命令,redis不會立即執行,而是讓當...

併發控制 悲觀鎖和樂觀鎖詳解

考慮下面兩個併發帶來的問題 1 丟失更新 乙個事務的更新結果覆蓋了其它事務的更新結果,即所謂的更新丟失。2 髒讀 當乙個事務讀取其它完成一半事務的記錄時,就會發生髒讀取。例如 兩個使用者同時修改商品庫存表,a b同時進入,看到的庫存都是100,a購買一件把庫存修改為99 100 1 此時b購買兩件把...