C# 基于 StackExchange.Redis 实现 分布式锁工具类
RedisLockService(完整实现)
using StackExchange.Redis; using System; using System.Threading.Tasks; public class RedisLockService { private readonly IDatabase _redis; private readonly TimeSpan _lockLeaseTime; // 锁过期时间 private readonly TimeSpan _lockTimeout; // 获取锁的等待时间 public RedisLockService(IConnectionMultiplexer connectionMultiplexer, TimeSpan? lockLeaseTime = null, TimeSpan? lockTimeout = null) { _redis = connectionMultiplexer.GetDatabase(); _lockLeaseTime = lockLeaseTime ?? TimeSpan.FromSeconds(10); // 默认锁 10 秒过期 _lockTimeout = lockTimeout ?? TimeSpan.FromSeconds(3); // 默认等待 3 秒 } /// <summary> /// 尝试获取分布式锁 /// </summary> public async Task<string?> LockAsync(string key) { key = $"Mall_lock:{key}"; var value = Guid.NewGuid().ToString(); // 锁的唯一标识 var start = DateTime.UtcNow; while (DateTime.UtcNow - start < _lockTimeout) { // NX:不存在时设置,PX:过期时间 bool acquired = await _redis.StringSetAsync( key, value, _lockLeaseTime, when: When.NotExists ); if (acquired) { return value; // 返回唯一标识,用于解锁 } await Task.Delay(100); // 等待重试 } return null; // 超时未获取到锁 } /// <summary> /// 解锁,只有持有锁的客户端才能解锁 /// </summary> public async Task<bool> UnlockAsync(string key, string value) { key = $"Mall_lock:{key}"; string script = @" if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end"; var result = (int)(long)await _redis.ScriptEvaluateAsync( script, keys: new RedisKey[] { key }, values: new RedisValue[] { value } ); return result == 1; } }
使用示例
var muxer = await ConnectionMultiplexer.ConnectAsync("localhost:6379"); var redisLockService = new RedisLockService(muxer); // 获取锁 string? lockValue = await redisLockService.LockAsync("order:123"); if (lockValue != null) { try { Console.WriteLine("加锁成功,执行业务逻辑..."); // TODO: 处理订单逻辑 } finally { // 解锁(必须传入获取锁时的 value,保证安全) bool unlocked = await redisLockService.UnlockAsync("order:123", lockValue); Console.WriteLine(unlocked ? "解锁成功" : "解锁失败"); } } else { Console.WriteLine("获取锁失败,请勿重复提交"); }
-
自动加前缀
Mall_lock: -
加锁时返回唯一标识(解锁必须带上,防止误删别人锁)
-
锁有过期时间,防止死锁
-
带超时等待逻辑

浙公网安备 33010602011771号