惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

酷 壳 – CoolShell
酷 壳 – CoolShell
H
Hacker News: Front Page
P
Palo Alto Networks Blog
T
ThreatConnect
Apple Machine Learning Research
Apple Machine Learning Research
博客园_首页
T
True Tiger Recordings
P
Privacy & Cybersecurity Law Blog
B
Blog
IT之家
IT之家
Last Week in AI
Last Week in AI
F
Full Disclosure
Hacker News: Ask HN
Hacker News: Ask HN
C
Comments on: Blog
Microsoft Azure Blog
Microsoft Azure Blog
C
Cybersecurity and Infrastructure Security Agency CISA
Microsoft Security Blog
Microsoft Security Blog
博客园 - 【当耐特】
N
News and Events Feed by Topic
NISL@THU
NISL@THU
腾讯CDC
雷峰网
雷峰网
Security Latest
Security Latest
李成银的技术随笔
M
Microsoft Research Blog - Microsoft Research
L
LangChain Blog
L
Lohrmann on Cybersecurity
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
C
Check Point Blog
Y
Y Combinator Blog
Recent Announcements
Recent Announcements
博客园 - Franky
N
News | PayPal Newsroom
V
V2EX
A
About on SuperTechFans
The Register - Security
The Register - Security
月光博客
月光博客
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Google Online Security Blog
Google Online Security Blog
MyScale Blog
MyScale Blog
Cisco Talos Blog
Cisco Talos Blog
Vercel News
Vercel News
WordPress大学
WordPress大学
C
Cyber Attacks, Cyber Crime and Cyber Security
The Hacker News
The Hacker News
IntelliJ IDEA : IntelliJ IDEA – the Leading IDE for Professional Development in Java and Kotlin | The JetBrains Blog
IntelliJ IDEA : IntelliJ IDEA – the Leading IDE for Professional Development in Java and Kotlin | The JetBrains Blog
爱范儿
爱范儿
A
Arctic Wolf
L
LINUX DO - 最新话题
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More

博客园 - 至尊龙骑

C# 使用FFmpeg 命令录音录像时设置 水印以及水印位置 C# 使用FFmpeg 命令 水印以及水印位置 录音录像时设置分辨率-分辨率一般是宽高比是 4:3 和16:9 少数是 5:4 FFmpeg 命令 水印以及水印位置 FFmpeg 命令录音录像时分辨率 FFmpeg 查看分辨率以及指定分辨率 C# 中监听 IPv6 回环地址----HttpListener C# 中监听 IPv6 回环地址(Loopback Address)----socket和tcp IPv6 地址 后端设置了跨域但是还是提示跨域问题,原因是这里有两个独立的安全策略在起作用:Chrome和Edge浏览器安全策略强制修改方案 开放所有跨域 ----前端和后端 Win11 上遇到的 WinForm 文件拖拽功能失效,但在 Win10 或其他系统上正常的问题 设置iis的后缀名可以下载 linux执行systemctl enable redis.service 报 Failed to execute operation: Bad message linux redis 8.2.1软件开机启动redis.service与etc下的rc.local配置2种方式 Linux redis 8.2.1源码编译 Linux开机启动设置全攻略 Linux 设置nginx 以及java jar自启动 Linux系统简单源码安装NGINX版本1.28.0 Windows 10\11 离线安装.NET Framework 3.5(包括.NET 2.0和3.0) - 至尊龙骑 跨域处理 utools无法搜索快捷方式和部分软件问题
DistributedLock 实现.Net分布式锁
至尊龙骑 · 2025-08-28 · via 博客园 - 至尊龙骑

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

  • • 多个服务节点同时写入数据库同一行数据
  • • 定时任务在多个节点上同时运行,导致重复执行
  • • 多实例写缓存时出现数据覆盖问题

为了解决 并发冲突 和 数据一致性 问题,就需要用到 分布式锁。

今天给大家介绍一个 .NET 里非常好用的分布式锁库 —— DistributedLock。

什么是 DistributedLock

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

  • • Redis
  • • SQL Server
  • • PostgreSQL
  • • MySQL
  • • MongoDB
  • • 内存模式(本地锁)

只需要更换存储提供程序,就能无缝地在不同的环境下使用。

基本使用

安装 NuGet 包

在项目中引入需要的后端依赖,如:

dotnet add package DistributedLock  --包含所有实现的元包
dotnet add package DistributedLock.Redis
dotnet add package DistributedLock.SqlServer

(Redis 和 SQL Server 是最常见的场景,也可以选择别的实现)

使用 Redis 分布式锁

  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 获取锁,代码块执行完毕后会自动释放,非常优雅。

使用 SQL Server 分布式锁

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);
        }
    }
}

续租机制与 RedLock

DistributedLock 的 Redis 实现内置了“看门狗”机制,定期检查锁是否仍由当前线程持有,并自动延长锁的过期时间,避免因业务处理时间过长导致锁失效。

DistributedLock 的 Redis 实现支持 RedLock 算法,通过在多个 Redis 节点上获取锁(至少 N/2+1 个节点)来确保高可靠性。RedLock 适合对一致性要求极高的场景。

适用场景

  • • 定时任务防重入(保证只有一个节点执行)
  • • 业务幂等控制(防止重复提交订单)
  • • 缓存击穿保护(避免多个实例同时回源数据库)
  • • 资源互斥访问(文件写入、消息处理等)

DistributedLock 是一个简单易用的分布式锁库,支持多种后端,特别适合用在微服务和分布式任务中。

如果你正在开发 分布式系统,强烈建议把它加入到你的工具库里。

原文链接:DistributedLock 实现.Net分布式锁