【netcore基礎】ConcurrentDictionary 使用字符串作爲key給代碼加鎖且使用EF事物防止併發調用數據混亂的問題

業務場景需要鎖住指定的字符串下的代碼,防止併發創建多個訂單

 

這裏我們使用

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

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章