由于无法关闭数据库连接,线程被阻塞

Posted

技术标签:

【中文标题】由于无法关闭数据库连接,线程被阻塞【英文标题】:Threads are blocked due to unable to close database connection 【发布时间】:2013-03-06 17:30:24 【问题描述】:

在堆栈跟踪中,MessageProcessor.Dispose()OnThreadShutdownRequestedRenewTaskLeaseCallback 都需要一个锁来防止这些对象中的竞争条件。 线程 (ID14968) 的堆栈跟踪保存了所有锁,这会导致其他线程阻塞并等待它释放锁。

问题在于,当在线程 14968 上调用 CloseConnection() 时,连接永远不会关闭,并且在 CloseConnection() 内部调用了 SyncAsyncLock.Wait()。调用被阻塞,无法继续,出现死锁情况。

在调用CloseConnection() 时,什么可能导致线程阻塞?

更大的图像here。

【问题讨论】:

图片链接因权限无法访问。 对不起,我的权限设置有误,现已修复。 【参考方案1】:

在解决这个问题两天后,我终于弄清楚了问题所在。 存在可能导致应用程序死锁的情况。

TaskLeaseRenewer 对象实现了IDisposable,可以被多个线程访问。在类内部使用锁来确保没有两个线程会尝试同时释放对象。 TaskLeaseRenewer 有一个计时器和回调函数Callback,它将由计时器在单独的线程上定期调用。 Callback 线程将尝试在创建TaskLeaseRenewer 的线程上调用Thread.Abort(),并最终在TaskLeaseRenwer 上调用Dispose()

当我尝试中止执行以下操作的线程时会出现问题:

using(TaskLeaseRenewer renewer = new TaskLeaseRewnewer())

    DoStuff();

我发现,当您在带有using 语句的线程上调用Thread.Abort() 时,它不会终止线程,直到它在使用的对象上调用Dispose() 函数。

下面的例子将在线程中止之前触发ConnectionWrapper.Dispose()

static void DisposeOnAbort()

    Thread t = new Thread(() =>
    
        Console.WriteLine("Using connection wrapper");
        using (ConnectionWrapper wrapper = new ConnectionWrapper())
        

            while (true)
            
                Thread.Sleep(1000);
            
        
    );
    t.Start();
    Thread.Sleep(1000);
    Console.WriteLine("Aborting thread..");
    t.Abort();

鉴于这些,我发现问题是当Callback() 调用Thread.Abort() 时,TaskLeaseRenewer.Dispose() 将在它创建的线程上被调用,因为线程正准备被杀死。但是Callback() 函数位于不同的线程上,并且还持有Dispose() 函数试图获取的锁。 Dispose() 将无法获取锁,线程永远不会终止。

解决这个问题后,connection.Close() 的死锁似乎消失了。我仍然对可能阻止连接关闭的原因感兴趣。

在更多地解决这个问题之后,我发现当一个线程被中止时,一次性对象的Dispose() 对象总是被调用。是否使用using 语句。调用栈如下:

Threads.exe!Threads.ConnectionWrapper.Dispose() Line 150    C#
Threads.exe!Threads.Program.DisposeOnAbort.AnonymousMethod__0() Line 58 + 0x2c bytes    C#

【讨论】:

以上是关于由于无法关闭数据库连接,线程被阻塞的主要内容,如果未能解决你的问题,请参考以下文章

Redis并发(转)

GRPC client阻塞导致无法及时关闭连接的解决方案

基于Netty构建高性能RPC通信框架

Mariadb的多线程连接问题

C# 多线程应用程序和 SQL 连接帮助

java 多次new DataOutputStream而不关闭,线程阻塞