You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用DistributedLock nuget的SQL分布式锁Dispose后未释放问题

问题根因
  • 核心问题是你所有分布式锁操作都复用了同一个全局静态SqlConnection实例,两个关键原因导致故障:
    1. SqlServer 提供的 sp_getapplock(DistributedLock 库底层依赖的原语)是会话级别的锁,锁的生命周期和所属的数据库连接(会话)直接绑定,同一连接会话持有锁时,同会话下的其他锁请求会被判定为重入,锁引用计数会叠加,单次Dispose只会减少计数不会真正释放锁,导致后续其他请求永远拿不到锁。
    2. ADO.NET 的 SqlConnection 本身不是线程安全类型,多个异步任务并发操作同一个连接实例,会触发未定义行为,进一步导致锁释放指令执行异常。
修复方案

去掉共用连接的逻辑,改为每次需要操作锁时创建独立的SqlConnection,ADO.NET内置的连接池会自动管理连接开销,不会有额外性能损耗,修正后的代码如下:

class Program
{
    // 替换全局连接为连接字符串
    private static string _connStr = "my connection string";
   
    static void Main(string[] args)
    {
        int pid;
        using (var p = Process.GetCurrentProcess()) { pid = p.Id; }
        TestSqlLocking(pid).Wait();
    }

    private static async Task TestSqlLocking(int processId)
    {
        var t1 = DoWorkAsyncWithSqlLock($"Process {processId} Client 1");
        var t2 = DoWorkAsyncWithSqlLock($"Process {processId} Client 2");
        var t3 = DoWorkAsyncWithSqlLock($"Process {processId} Client 3");
        var t4 = DoWorkAsyncWithSqlLock($"Process {processId} Client 4");
        await Task.WhenAll(t1, t2, t3, t4);
    }

    private static async Task DoWorkAsyncWithSqlLock(string client)
    {
        // 每个任务独立创建连接
        await using var sqlConn = new SqlConnection(_connStr);
        await sqlConn.OpenAsync();
        var sqlDistributedLock = new SqlDistributedLock("myLock", sqlConn);
        Console.WriteLine($"SQL Before taking the lock for client [{client}]");
        await using (await sqlDistributedLock.AcquireAsync(TimeSpan.FromSeconds(10)))
        {
            Console.WriteLine($"SQL After taking the lock and doing some work for client [{client}]");
            await Task.Delay(1000);
            Console.WriteLine($"SQL After doing some work and releasing lock for client [{client}]");
        }
    }
}
  • 补充说明:如果你的场景确实需要复用连接,必须确保同一时间只有一个线程操作该连接,且锁操作串行执行,这种方案性能会大幅下降,不推荐使用。

内容的提问来源于stack exchange,提问作者Michał Turczyn

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.07 09:15:02