已回答 线程锁定-Db超时

etl2016

活跃的成员
已加入
2016年6月29日
留言内容
39
编程经验
3-5
你好

我在应用程序中旋转了近40个线程,所有线程都通过线程锁定功能访问数据库。每个线程正在处理大约十万行。我收到数据库超时错误。我已经使用了连接池机制。我想仔细研究一下,找出三个可能的原因之一。

第一,DB的效率不足以处理给定线程内的调用(因为线程锁已在使用中)。如果是这样,则其连接功能(或类似功能)需要升级。连接在5000ms内超时。

二,线程锁没有正确实现。

第三,connectionpool没有正确实现。如何以编程方式诊断实际原因以查明根本原因?


谢谢
 

跳伞

工作人员
已加入
2019年4月6日
留言内容
2,497
地点
弗吉尼亚州切萨皮克
编程经验
10+
如果不看代码,就很难评论数据库与线程锁的交互方式。
 

跳伞

工作人员
已加入
2019年4月6日
留言内容
2,497
地点
弗吉尼亚州切萨皮克
编程经验
10+
请告诉我您未将代码编写为:
C#:
using (var connection = new SqlConnection( ... ))
{
    connection.Open();
    lock (lockObject)
    {
        // do database operation here...
    }
}
使用上面的这种代码结构,您可以在等待线程锁清除的同时保持连接打开。

我想知道为什么您甚至需要线程锁。 (实施良好)数据库显示 行为。您是否正在尝试某种与数据库保持一致的内存数据结构,因此需要线程锁定以使您的内存表示形式也具有ACID行为?
 

etl2016

活跃的成员
已加入
2016年6月29日
留言内容
39
编程经验
3-5
谢谢跳伞者

超时与此有关: 您是否受到网络或CPU的限制?


核心问题似乎与ThreadPooling / IOCP / qs有关

我实现的锁如下所示,它无法处理线程被盗和连接超时的情况:我已经绕了数百个线程

C#:
static readonly object UpdateLock = new object ();
public static void UpdateDBUtility (some parameters)
{
    lock (UpdateLock)
   {
        update  the database;
   }
}
 
由主持人最后编辑:

跳伞

工作人员
已加入
2019年4月6日
留言内容
2,497
地点
弗吉尼亚州切萨皮克
编程经验
10+
您上面的链接是关于Redis的。您打开了一个问题,说您正在使用SQL。您是否将Redis用作SQL的前端缓存?

上面的代码片段仍未显示您在何时获取连接。您是否打开并使用锁中的连接?还是您做错了方式,就像我在第一次答复中担心的那样?
 

跳伞

工作人员
已加入
2019年4月6日
留言内容
2,497
地点
弗吉尼亚州切萨皮克
编程经验
10+
我已经绕了一百根纱
您是否有支持此功能的核心数量?一个好的经验法则是每个内核大约2-4个线程。
 

etl2016

活跃的成员
已加入
2016年6月29日
留言内容
39
编程经验
3-5
"...您是否将Redis用作SQL的前端缓存?..."否。它仅用于进行查找以转换输入中的特定列。"...您是否打开并使用锁内的连接...."在线程化之前,连接仅打开一次,并在所有子线程中重新使用。 Redis提供了一种称为多路复用的机制。它的实现方式如下: 基本用法

".....一个好的经验法则是每个内核大约2-4个线程....."谢谢。我有四个核心的设置。因此,将我的线程从一百个减至十个十。

谢谢
 

跳伞

工作人员
已加入
2019年4月6日
留言内容
2,497
地点
弗吉尼亚州切萨皮克
编程经验
10+
是的,对于Redis可能是正确的,但是对于SQL连接,您不应打开一次并在所有线程之间共享。对于SQL连接,您需要实例化并在同一线程中使用它。
 

羊皮

退休程序员
工作人员
已加入
2018年9月5日
留言内容
1,921
地点
英国
编程经验
10+
一个好的经验法则是每个内核大约2-4个线程。
除非您要尝试计算有多少个内核,否则建议不要超出无法解释的范围。
 
最佳 底部