c# - 具有多线程服务的数据库连接池

标签 c# multithreading service connection-pooling

我有一个使用 TPL 库进行线程处理的 .NET 4 C# 服务。我们最近将其切换为也使用连接池,因为一个连接正在成为处理的瓶颈。

以前,我们使用锁定子句来控制连接对象上的线程安全。随着工作的备份,队列将作为任务存在,并且许多线程(任务)将等待锁定子句。现在,在大多数情况下,线程等待数据库 IO 和工作进程要快得多。

但是,既然我正在使用连接池,我们就会遇到一个新问题。一旦达到最大连接数(默认为 100),如果请求更多连接,则会超时(请参阅 Pooling info )。发生这种情况时,会抛出一个异常,提示“连接请求超时”。

我所有的 IDisposables 都在 using 语句中,并且我正确地管理了我的连接。这种情况的发生是由于请求的工作多于池可以处理的(这是预期的)。我明白为什么抛出这个异常,并且知道处理它的方法。一个简单的重试感觉就像一个 hack。我还意识到我可以通过连接字符串增加超时时间,但这并不是一个可靠的解决方案。在以前的设计(没有池化)中,工作项会因为应用程序中的锁而被处理。

处理这种情况以确保所有工作都得到处理的好方法是什么?

最佳答案

另一种方法是使用 semaphore围绕从池中检索连接的代码(并希望返回它们)。 sempahore 类似于 lock 语句,不同之处在于它一次允许可配置数量的请求者,而不仅仅是一个。

应该这样做:

//Assuming mySemaphore is a semaphore instance, e.g. 
// public static Semaphore mySemaphore = new Semaphore(100,100);
try {
  mySemaphore.WaitOne(); // This will block until a slot is available.
  DosomeDatabaseLogic();
} finally {
  mySemaphore.Release();
}

关于c# - 具有多线程服务的数据库连接池,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8762678/

相关文章:

c# - 关于创建隐藏文件夹的问题

c# - 循环遍历数组问题的内容

java - 我们可以在线程执行时更改线程的优先级吗?更改会发生还是操作系统会忽略它?(Java)

java - 如何让我的程序等待特定线程并且不影响我的 GUI 的交互性?

c# - 以编程方式限制在服务中运行的线程的 CPU 使用率

docker - Ansible服务重启不起作用

wcf - Reporting Services LocalReport和WIF

c# - 使用线程安全的 .NET 4+ 集合时是否可能导致死锁?

c# - 如何转换 Feb 19, 2015,22 :19:50 to 2/19/2015 22:19:50 in C#?

android - 使用多个线程下载图像会导致 OutOfMemory 异常