業務場景須要鎖住指定的字符串下的代碼,防止併發建立多個訂單redis
這裏咱們使用服務器
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共享keyspa
而後在須要寫入多個表的地方添加 事物處理code
using (var _trs = _orderService.GetDB().BeginTransaction()) { try { //todo... _trs.Commit(); } catch (Exception ex) { _trs.Rollback(); throw new GeduException(ex.Message); } finally { GeduRedisHelper.Remove(lockkey); }
這樣能夠防止數據部分紅功部分失敗的問題blog
最後操做成功以後要清理掉 redis 裏的lock字符串