找回密码
 立即注册
首页 业界区 安全 DistributedLock 实现.Net分布式锁

DistributedLock 实现.Net分布式锁

笃扇 4 天前
在分布式系统中,经常会遇到多个实例同时访问同一份资源的情况,例如:

  • • 多个服务节点同时写入数据库同一行数据
  • • 定时任务在多个节点上同时运行,导致重复执行
  • • 多实例写缓存时出现数据覆盖问题
为了解决 并发冲突 和 数据一致性 问题,就需要用到 分布式锁。
今天给大家介绍一个 .NET 里非常好用的分布式锁库 —— DistributedLock。
什么是 DistributedLock

DistributedLock 是一个轻量级、线程安全的 .NET 库,用来在分布式环境下实现锁的功能。支持多种后端存储,包括:

  • • Redis
  • • SQL Server
  • • PostgreSQL
  • • MySQL
  • • MongoDB
  • • 内存模式(本地锁)
只需要更换存储提供程序,就能无缝地在不同的环境下使用。
基本使用

安装 NuGet 包

在项目中引入需要的后端依赖,如:
  1. dotnet add package DistributedLock  --包含所有实现的元包
  2. dotnet add package DistributedLock.Redis
  3. dotnet add package DistributedLock.SqlServer
复制代码
 
(Redis 和 SQL Server 是最常见的场景,也可以选择别的实现)
使用 Redis 分布式锁
  1.   var RedisConnectionString = "localhost:6379,abortConnect=false";
  2.   var LockName = "MyResourceLock";
  3.   var connection = await ConnectionMultiplexer.ConnectAsync(RedisConnectionString); // uses StackExchange.Redis
  4.   var @lock = new RedisDistributedLock(LockName, connection.GetDatabase());
  5.   await using (var handle = await @lock.TryAcquireAsync())
  6.   {
  7.       if (handle != null) { /* I have the lock */ }
  8.   }
复制代码
 
只要使用 Acquire / AcquireAsync 获取锁,代码块执行完毕后会自动释放,非常优雅。
使用 SQL Server 分布式锁
  1. using Medallion.Threading.SqlServer;
  2. using System;
  3. using System.Threading;
  4. using System.Threading.Tasks;
  5. namespace DistributedLockDemo
  6. {
  7.     internal class Program
  8.     {
  9.         static async Task Main(string[] args)
  10.         {
  11.             var connectionString = "Server=myServerAddress;Database=Locks;User Id=myUsername;Password=myPassword;";
  12.             var lockName = "MyResourceLock";
  13.             // 创建分布式锁对象(不需要 using,因为它不实现 IDisposable)
  14.             var sqlLock = new SqlDistributedLock(lockName, connectionString);
  15.             // 尝试获取锁,返回的锁句柄(LockHandle)实现了 IDisposable
  16.             using (var lockHandle = sqlLock.TryAcquire(TimeSpan.FromSeconds(30)))
  17.             {
  18.                 if (lockHandle != null) // 判断是否成功获取锁
  19.                 {
  20.                     // 持有锁,执行需要同步的代码
  21.                     Console.WriteLine("Lock acquired, performing operation...");
  22.                     // 模拟业务操作
  23.                     await Task.Delay(1000); // 建议使用异步延迟而非 Thread.Sleep
  24.                 }
  25.                 else
  26.                 {
  27.                     Console.WriteLine("Failed to acquire lock within the timeout.");
  28.                 }
  29.             } // 此处会自动释放锁(lockHandle.Dispose())
  30.         }
  31.     }
  32. }
复制代码
 
在 定时任务(Quartz、Hangfire 等) 场景中,特别适合用来避免多节点重复执行。
依赖注入集成

appsettings.json
  1. {
  2.   "ConnectionStrings": {
  3.     "SqlServer": "Server=myServerAddress;Database=Locks;User Id=myUsername;Password=myPassword;",
  4.     "Redis": "localhost:6379"
  5.   }
  6. }
复制代码
 
DistributedLock 支持依赖注入,适合在项目中使用。
  1. // Startup.cs 或 Program.cs
复制代码
  1. public void ConfigureServices(IServiceCollection services)
  2. {
  3.     var connectionString = Configuration.GetConnectionString("SqlServer");
  4.     services.AddSingleton<IDistributedLockProvider>(_ =>
  5.         new SqlDistributedSynchronizationProvider(connectionString));
  6.     services.AddTransient<SomeService>();
  7. }
复制代码
 
  1. // SomeService.cs
复制代码
  1. public class SomeService
  2. {
  3.     private readonly IDistributedLockProvider _lockProvider;
  4.     public SomeService(IDistributedLockProvider lockProvider)
  5.     {
  6.         _lockProvider = lockProvider;
  7.     }
  8.     public async Task InitializeUserAccountAsync(int id)
  9.     {
  10.         var @lock = _lockProvider.CreateLock(#34;UserAccount{id}");
  11.         await using (await @lock.AcquireAsync())
  12.         {
  13.             // 执行需要同步的操作
  14.             Console.WriteLine(#34;Initializing user account {id}...");
  15.             await Task.Delay(1000);
  16.         }
  17.     }
  18. }
复制代码
 
  1.  
复制代码
续租机制与 RedLock

DistributedLock 的 Redis 实现内置了“看门狗”机制,定期检查锁是否仍由当前线程持有,并自动延长锁的过期时间,避免因业务处理时间过长导致锁失效。
DistributedLock 的 Redis 实现支持 RedLock 算法,通过在多个 Redis 节点上获取锁(至少 N/2+1 个节点)来确保高可靠性。RedLock 适合对一致性要求极高的场景。
适用场景


  • • 定时任务防重入(保证只有一个节点执行)
  • • 业务幂等控制(防止重复提交订单)
  • • 缓存击穿保护(避免多个实例同时回源数据库)
  • • 资源互斥访问(文件写入、消息处理等)
DistributedLock 是一个简单易用的分布式锁库,支持多种后端,特别适合用在微服务和分布式任务中。
如果你正在开发 分布式系统,强烈建议把它加入到你的工具库里。
原文链接:DistributedLock 实现.Net分布式锁

来源:豆瓜网用户自行投稿发布,如果侵权,请联系站长删除

相关推荐

您需要登录后才可以回帖 登录 | 立即注册