添加项目文件。
This commit is contained in:
@@ -0,0 +1,175 @@
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace RedisHelper
|
||||
{
|
||||
public class DistributedLock : IDistributedLock
|
||||
{
|
||||
private readonly ICache _cache;
|
||||
private readonly ILogger<DistributedLock> _logger;
|
||||
|
||||
public DistributedLock(ICache cache, ILogger<DistributedLock> logger)
|
||||
{
|
||||
_cache = cache;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
public async Task<T> TryExecuteAsync<T>(string key, Func<Task<T>> action, int expiry = 30, bool retry = false, int retryDelay = 100)
|
||||
{
|
||||
string lockKey = GetLockKey(key);
|
||||
string lockValue = Guid.NewGuid().ToString();
|
||||
|
||||
while (true)
|
||||
{
|
||||
if (TryAcquireLock(lockKey, lockValue, expiry))
|
||||
{
|
||||
try
|
||||
{
|
||||
return await action();
|
||||
}
|
||||
finally
|
||||
{
|
||||
ReleaseLock(lockKey, lockValue);
|
||||
}
|
||||
}
|
||||
|
||||
if (!retry)
|
||||
{
|
||||
return default(T);
|
||||
}
|
||||
|
||||
await Task.Delay(retryDelay);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<bool> TryExecuteAsync(string key, Func<Task> action, int expiry = 30, bool retry = false, int retryDelay = 100)
|
||||
{
|
||||
string lockKey = GetLockKey(key);
|
||||
string lockValue = Guid.NewGuid().ToString();
|
||||
|
||||
while (true)
|
||||
{
|
||||
if (TryAcquireLock(lockKey, lockValue, expiry))
|
||||
{
|
||||
try
|
||||
{
|
||||
await action();
|
||||
return true;
|
||||
}
|
||||
finally
|
||||
{
|
||||
ReleaseLock(lockKey, lockValue);
|
||||
}
|
||||
}
|
||||
|
||||
if (!retry)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
await Task.Delay(retryDelay);
|
||||
}
|
||||
}
|
||||
|
||||
public T TryExecute<T>(string key, Func<T> action, int expiry = 30, bool retry = false, int retryDelay = 100)
|
||||
{
|
||||
string lockKey = GetLockKey(key);
|
||||
string lockValue = Guid.NewGuid().ToString();
|
||||
|
||||
while (true)
|
||||
{
|
||||
if (TryAcquireLock(lockKey, lockValue, expiry))
|
||||
{
|
||||
try
|
||||
{
|
||||
return action();
|
||||
}
|
||||
finally
|
||||
{
|
||||
ReleaseLock(lockKey, lockValue);
|
||||
}
|
||||
}
|
||||
|
||||
if (!retry)
|
||||
{
|
||||
return default(T);
|
||||
}
|
||||
|
||||
Thread.Sleep(retryDelay);
|
||||
}
|
||||
}
|
||||
|
||||
public bool TryExecute(string key, Action action, int expiry = 30, bool retry = false, int retryDelay = 100)
|
||||
{
|
||||
string lockKey = GetLockKey(key);
|
||||
string lockValue = Guid.NewGuid().ToString();
|
||||
|
||||
while (true)
|
||||
{
|
||||
if (TryAcquireLock(lockKey, lockValue, expiry))
|
||||
{
|
||||
try
|
||||
{
|
||||
action();
|
||||
return true;
|
||||
}
|
||||
finally
|
||||
{
|
||||
ReleaseLock(lockKey, lockValue);
|
||||
}
|
||||
}
|
||||
|
||||
if (!retry)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
Thread.Sleep(retryDelay);
|
||||
}
|
||||
}
|
||||
|
||||
private bool TryAcquireLock(string lockKey, string lockValue, int expiry)
|
||||
{
|
||||
try
|
||||
{
|
||||
var redis = _cache.GetFullRedis();
|
||||
|
||||
bool acquired = redis.Add(lockKey, lockValue, expiry);
|
||||
|
||||
if (acquired)
|
||||
{
|
||||
}
|
||||
|
||||
return acquired;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, $"获取分布式锁时发生错�? {lockKey}");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private void ReleaseLock(string lockKey, string lockValue)
|
||||
{
|
||||
try
|
||||
{
|
||||
var redis = _cache.GetFullRedis();
|
||||
|
||||
var currentValue = redis.Get<string>(lockKey);
|
||||
|
||||
if (currentValue == lockValue)
|
||||
{
|
||||
redis.Remove(lockKey);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, $"释放分布式锁时发生错�? {lockKey}");
|
||||
}
|
||||
}
|
||||
|
||||
private string GetLockKey(string key)
|
||||
{
|
||||
return $"{key}";
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user