72 lines
2.3 KiB
C#
72 lines
2.3 KiB
C#
|
|
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;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|