你的位置:首页 > 软件开发 > ASP.net > .net 分布式锁实现

.net 分布式锁实现

发布时间:2015-11-05 10:00:42
分布式锁经常用于在解决分布式环境下的业务一致性和协调分布式环境。实际业务场景中,比如说解决并发一瞬间的重复下单,重复确认收货,重复发现金券等。使用分布式锁的场景一般不能太多。 开源地址:http://git.oschina.net/chejiangyi/XXF.BaseSer ...

分布式锁

经常用于在解决分布式环境下的业务一致性和协调分布式环境。

实际业务场景中,比如说解决并发一瞬间的重复下单,重复确认收货,重复发现金券等。

使用分布式锁的场景一般不能太多。

 

开源地址:http://git.oschina.net/chejiangyi/XXF.BaseService.DistributedLock

开源相关群: .net 开源基础服务 238543768

这里整理了C#.net关于redis分布式锁和zookeeper分布式锁的实现,仅用于研究。(可能有bug)

采用ServiceStack.Redis实现Redis分布式锁

 
/*   * Redis分布式锁   * 采用ServiceStack.Redis实现的Redis分布式锁   * 详情可阅读其开源代码   * 备注:不同版本的 ServiceStack.Redis 实现reidslock机制不同 xxf里面默认使用2.2版本   */  public class RedisDistributedLock : BaseRedisDistributedLock  {    private ServiceStack.Redis.RedisLock _lock;    private RedisClient _client;    public RedisDistributedLock(get='_blank'>string redisserver, string key)      : base(redisserver, key)    {     }     public override LockResult TryGetDistributedLock(TimeSpan? getlockTimeOut, TimeSpan? taskrunTimeOut)    {      if (lockresult == LockResult.Success)        throw new DistributedLockException("检测到当前锁已获取");      _client = DistributedLockConfig.GetRedisPoolClient(redisserver).GetClient();      /*       * 阅读源码发现当其获取锁后,redis连接资源会一直占用,知道获取锁的资源释放后,连接才会跳出,可能会导致连接池资源的浪费。       */      try      {        this._lock = new ServiceStack.Redis.RedisLock(_client, key, getlockTimeOut);        lockresult = LockResult.Success;      }      catch (Exception exp)      {        XXF.Log.ErrorLog.Write(string.Format("redis分布式尝试锁系统级别严重异常,redisserver:{0}", redisserver.NullToEmpty()), exp);        lockresult = LockResult.LockSystemExceptionFailure;      }      return lockresult;    }     public override void Dispose()    {      try      {        if (this._lock != null)          this._lock.Dispose();        if (_client != null)          this._client.Dispose();      }      catch (Exception exp)      {        XXF.Log.ErrorLog.Write(string.Format("redis分布式尝试锁释放严重异常,redisserver:{0}", redisserver.NullToEmpty()), exp);      }    }  }
              bool acquired = redisclient.Add<long>(@lock, value, TimeSpan.FromMilliseconds(taskexpiredMilliseconds + DistributedLockConfig.TaskLockDelayCleepUpTime)); //SETNX成功,则成功获取一个锁 if (acquired == true) { lockresult = LockResult.Success; } //SETNX失败,说明锁仍然被其他对象保持,检查其是否已经超时                   var getValueBytes = redisclient.GetSet(@lock, BitConverter.GetBytes(value)); var o1 = redisclient.ExpireEntryIn(@lock, TimeSpan.FromMilliseconds(taskexpiredMilliseconds + DistributedLockConfig.TaskLockDelayCleepUpTime));//这里如果程序异常终止,依然会有部分锁未释放的情况。 // 获取锁成功 if (getValueBytes == oldValueBytes) { lockresult = LockResult.Success; } // 已被其他进程捷足先登了 else { lockresult = LockResult.GetLockTimeOutFailure; } } //未超时,则直接返回失败 else { lockresult = LockResult.GetLockTimeOutFailure; } } } //成功拿到锁 if (lockresult == LockResult.Success) break; //获取锁超时 if (hassleepMilliseconds >= getlockexpiredMilliseconds) { lockresult = LockResult.GetLockTimeOutFailure; break; } //继续等待 System.Threading.Thread.Sleep(DistributedLockConfig.GetLockFailSleepTime); hassleepMilliseconds += DistributedLockConfig.GetLockFailSleepTime; } } catch (Exception exp) { XXF.Log.ErrorLog.Write(string.Format("redis分布式尝试锁系统级别严重异常,redisserver:{0}", redisserver.NullToEmpty()), exp); lockresult = LockResult.LockSystemExceptionFailure; } return lockresult; } private long CurrentUnixTimeMillis() { return (long)(System.DateTime.UtcNow - new System.DateTime(1970, 1, 1, 0, 0, 0, System.DateTimeKind.Utc)).TotalMilliseconds; } public override void Dispose() { if (lockresult == LockResult.Success || lockresult == LockResult.LockSystemExceptionFailure) { try { long current = CurrentUnixTimeMillis(); using (var redisclient = DistributedLockConfig.GetRedisPoolClient(redisserver).GetClient()) { var v = redisclient.Get(key); if (v != null) { // 避免删除非自己获取得到的锁 if (current < BitConverter.ToInt64(v, 0)) { redisclient.Del(key); } } } } catch (Exception exp) { XXF.Log.ErrorLog.Write(string.Format("redis分布式尝试锁释放严重异常,redisserver:{0}", redisserver.NullToEmpty()), exp); } } } }

 

海外公司注册、海外银行开户、跨境平台代入驻、VAT、EPR等知识和在线办理:https://www.xlkjsw.com

原标题:.net 分布式锁实现

关键词:.NET

*特别声明:以上内容来自于网络收集,著作权属原作者所有,如有侵权,请联系我们: admin#shaoqun.com (#换成@)。