Files
juipnet/Infrastructure/Hncore.Infrastructure/Common/RedisLocklHelper.cs

72 lines
2.3 KiB
C#
Raw Normal View History

2024-04-10 13:55:27 +08:00
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;
/// <summary>
///
/// </summary>
/// <param name="key">锁的键</param>
/// <param name="outTime">锁超时时间 单位毫秒</param>
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;
}
}
}