【netcore基礎】ConcurrentDictionary 使用字串作為key給程式碼加鎖且使用EF事物防止併發呼叫資料混亂的問題
阿新 • • 發佈:2019-01-04
業務場景需要鎖住指定的字串下的程式碼,防止併發建立多個訂單
這裡我們使用
ConcurrentDictionary
首先初始化一個字典
private static readonly ConcurrentDictionary<string, string> _dictLock = new ConcurrentDictionary<string, string>();
然後使用定義一個要鎖程式碼的的key,這裡為保證每個訂單唯一,使用微信的訂單號作為key
對同一微信支付訂單的回撥進行加鎖處理程式碼
var lockkey = "wxpay_callback_lock_" + MD5Helper.GetMD5Str(pay.out_trade_no + pay.transaction_id); ; lock (_dictLock.GetOrAdd(lockkey, lockkey)) { if (GeduRedisHelper.Exists(lockkey)) { throw new GeduException("操作正在處理,請勿重複請求"); } GeduRedisHelper.Add(lockkey, new { pay.out_trade_no, pay.transaction_id }, 60); }
在lock程式碼段裡我們使用 redis 來判斷是否存在,為了方便以後分散式部署多臺伺服器的併發問題,這裡可以redis共享key
然後在需要寫入多個表的地方新增 事物處理
using (var _trs = _orderService.GetDB().BeginTransaction()) { try { //todo... _trs.Commit(); } catch (Exception ex) { _trs.Rollback(); throw new GeduException(ex.Message); } finally { GeduRedisHelper.Remove(lockkey); }
這樣可以防止資料部分成功部分失敗的問題
最後操作成功之後要清理掉 redis 裡的lock