






















在分布式系统中,经常会遇到多个实例同时访问同一份资源的情况,例如:
为了解决 并发冲突 和 数据一致性 问题,就需要用到 分布式锁。
今天给大家介绍一个 .NET 里非常好用的分布式锁库 —— DistributedLock。
DistributedLock 是一个轻量级、线程安全的 .NET 库,用来在分布式环境下实现锁的功能。支持多种后端存储,包括:
只需要更换存储提供程序,就能无缝地在不同的环境下使用。
在项目中引入需要的后端依赖,如:
dotnet add package DistributedLock --包含所有实现的元包
dotnet add package DistributedLock.Redis
dotnet add package DistributedLock.SqlServer
(Redis 和 SQL Server 是最常见的场景,也可以选择别的实现)
var RedisConnectionString = "localhost:6379,abortConnect=false"; var LockName = "MyResourceLock"; var connection = await ConnectionMultiplexer.ConnectAsync(RedisConnectionString); // uses StackExchange.Redis var @lock = new RedisDistributedLock(LockName, connection.GetDatabase()); await using (var handle = await @lock.TryAcquireAsync()) { if (handle != null) { /* I have the lock */ } }
只要使用 Acquire / AcquireAsync 获取锁,代码块执行完毕后会自动释放,非常优雅。
using Medallion.Threading.SqlServer; using System; using System.Threading; using System.Threading.Tasks; namespace DistributedLockDemo { internal class Program { static async Task Main(string[] args) { var connectionString = "Server=myServerAddress;Database=Locks;User Id=myUsername;Password=myPassword;"; var lockName = "MyResourceLock"; // 创建分布式锁对象(不需要 using,因为它不实现 IDisposable) var sqlLock = new SqlDistributedLock(lockName, connectionString); // 尝试获取锁,返回的锁句柄(LockHandle)实现了 IDisposable using (var lockHandle = sqlLock.TryAcquire(TimeSpan.FromSeconds(30))) { if (lockHandle != null) // 判断是否成功获取锁 { // 持有锁,执行需要同步的代码 Console.WriteLine("Lock acquired, performing operation..."); // 模拟业务操作 await Task.Delay(1000); // 建议使用异步延迟而非 Thread.Sleep } else { Console.WriteLine("Failed to acquire lock within the timeout."); } } // 此处会自动释放锁(lockHandle.Dispose()) } } }
在 定时任务(Quartz、Hangfire 等) 场景中,特别适合用来避免多节点重复执行。
appsettings.json
{ "ConnectionStrings": { "SqlServer": "Server=myServerAddress;Database=Locks;User Id=myUsername;Password=myPassword;", "Redis": "localhost:6379" } }
DistributedLock 支持依赖注入,适合在项目中使用。
// Startup.cs 或 Program.cs
public void ConfigureServices(IServiceCollection services) { var connectionString = Configuration.GetConnectionString("SqlServer"); services.AddSingleton<IDistributedLockProvider>(_ => new SqlDistributedSynchronizationProvider(connectionString)); services.AddTransient<SomeService>(); }
public class SomeService { private readonly IDistributedLockProvider _lockProvider; public SomeService(IDistributedLockProvider lockProvider) { _lockProvider = lockProvider; } public async Task InitializeUserAccountAsync(int id) { var @lock = _lockProvider.CreateLock(#34;UserAccount{id}"); await using (await @lock.AcquireAsync()) { // 执行需要同步的操作 Console.WriteLine(#34;Initializing user account {id}..."); await Task.Delay(1000); } } }
DistributedLock 的 Redis 实现内置了“看门狗”机制,定期检查锁是否仍由当前线程持有,并自动延长锁的过期时间,避免因业务处理时间过长导致锁失效。
DistributedLock 的 Redis 实现支持 RedLock 算法,通过在多个 Redis 节点上获取锁(至少 N/2+1 个节点)来确保高可靠性。RedLock 适合对一致性要求极高的场景。
DistributedLock 是一个简单易用的分布式锁库,支持多种后端,特别适合用在微服务和分布式任务中。
如果你正在开发 分布式系统,强烈建议把它加入到你的工具库里。
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。