using Hncore.Infrastructure.Extension; using System; using System.Diagnostics; using System.Reflection; using System.Runtime.InteropServices; namespace Hncore.Infrastructure.Common { public class RedisLocker { private string _key; private long _lockTime; /// /// /// /// 锁的键 /// 锁超时时间 单位毫秒 public RedisLocker(string key,long outTime) { _key =$"Lock:{Assembly.GetCallingAssembly().GetFriendName()}:{key}" ; _lockTime = outTime; } public void Exec(Action action) { if (GetLock()) { action(); ReleaseLock(); } } protected bool GetLock() { try { var currentTime = DateTime.Now.GetUnixTimeStamp(); if (RedisHelper.SetNx(this._key, currentTime + _lockTime)) { Console.WriteLine("获取到Redis锁了"); RedisHelper.Expire(_key, TimeSpan.FromMilliseconds(_lockTime)); //设置过期时间 return true; } //防止SetNx成功但是设置过期时间(Expire)失败造成死锁 var lockValue = Convert.ToInt64(RedisHelper.Get(_key)); currentTime = DateTime.Now.GetUnixTimeStamp(); if (lockValue > 0 && currentTime > lockValue) { var getsetResult = Convert.ToInt64(RedisHelper.GetSet(_key, currentTime)); if (getsetResult == 0 || getsetResult == lockValue) { Console.WriteLine("获取到Redis锁了"); RedisHelper.Expire(_key, TimeSpan.FromMilliseconds(_lockTime)); return true; } } Console.WriteLine("没有获取到锁"); return false; } catch { ReleaseLock(); return false; } } protected bool ReleaseLock() { return RedisHelper.Del(_key) > 0; } } }