业务场景须要锁住指定的字符串下的代码,防止并发建立多个订单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字符串