【问题标题】:How to minimize concurrent database connections?如何最小化并发数据库连接?
【发布时间】:2012-12-01 07:42:09
【问题描述】:

我的托管公司阻止我的网站使用超过 15 个并发数据库连接。但是在我的代码中,我关闭了我打开的每一个连接。但是他们仍然说并发连接太多。并建议我应该更改我网站的源代码的解决方案。那么请告诉我有关此问题的解决方案?而且我的网站是动态的,所以将其设为静态的简单 HTML 旧日类型会有所不同吗?

另请注意,我在没有想到任何解决方案的情况下尝试了这个,在每个con.open() 之前,我添加了con.Close(),这样任何其他打开的连接都将被关闭。

【问题讨论】:

  • 通常连接在打开后关闭。你的方法有些地方不太对劲。
  • 其实我是为了解决这个问题。我知道连接只能在打开后关闭,但作为试验我这样做了。
  • 如何在打开之前关闭连接对我有帮助……除非你有一大堆静态连接(或存储在会话变量中)来增加连接池……

标签: c# asp.net sql-server-2008 connection database-connection


【解决方案1】:

要做的第一件事是检查何时打开连接 - 看看是否可以将其最小化。例如,你在不同的连接上做“n+1”?

如果您有一个单一服务器,这里的技术解决方案是信号量 - 例如,类似:

someSemaphore.TakeOne();
try {
    using(var conn = GetConnection()) {
        ...
    }
} finally {
    someSemaphore.Release();
}

这将(假设 someSemaphore 是共享的,例如static)确保您一次只能进入该块“n”次。在您的情况下,您将创建具有 15 个空格的信号量:

static readonly Semaphore someSemaphore = new Semaphore(15,15);

但是!建议注意:在某些情况下,您可能会遇到死锁:想象 2 个写得不好的线程,每个线程需要 9 个连接 - 线程 A 需要 7 个,线程 B 需要 8 个。它们都需要更多 - 并且都不会得到它们。因此,使用带有超时的WaitOne 很重要:

static void TakeConnection() {
     if(!someSemaphore.TakeOne(3000)) {
         throw new TimeoutException("Unable to reserve connection");
     }
}
static void ReleaseConnection() {
     someSemaphore.Release();
}
...
TakeConnection();
try {
    using(var conn = GetConnection()) {
        ...
    }
} finally {
    ReleaseConnection();
}

也可以将其封装在IDisposable 中,以方便使用。

【讨论】:

  • +1。不错的建议...我也猜想 OP 只需要用using 包装所有连接的使用并在连接池上中继以共享连接...无论如何,15 个并发请求并不是那么小的限制...
【解决方案2】:

更改托管公司。

说真的。

除非你经营一个可怜的小家庭博客。

您可以轻松地同时处理超过 15 个页面/请求。我总是对“失控的连接”保持警惕,但我认为 15 连接甚至不值得一提。这就像一家汽车租赁公司抱怨你开车超过 15 公里 - 这简直是一个非常低的限制。

在繁忙的网站上,您可以有 50、100 甚至 200 个打开的连接,因为您同时处理了那么多请求。

【讨论】:

  • 但由于我们的预算很低,所以我们选择了这家公司。你能推荐另一家适合我的低预算公司吗?
  • 不知道。看,我不使用提供商托管网站。我在我的服务器公园里托管我的东西。我的每月升级预算是 - 不平凡。我们只是为新服务器安装了 15 千瓦的 USV ;) 但是很抱歉,如果您的预算不允许您需要的主机,请调整预算或关闭 ite 并回家。您可能会谈论价格范围底部的主机 - 猜猜看,您得到了您所支付的费用。
【解决方案3】:

这不是很明显,但即使您关心正确打开和关闭您的连接,您也必须看一些特别的东西。

如果您对用于构建连接字符串的文本进行最小的更改,.net 将创建一个全新的连接,而不是使用已打开的连接(即使该连接使用 MARS),因此以防万一,寻找如果您正在动态创建连接字符串而不是使用 Web 配置中的单个连接字符串,则您的代码。

【讨论】:

  • 不,我正在使用 web.config 访问连接字符串和单个连接字符串
【解决方案4】:

我相信 SQL 连接是池化的。当你关闭一个时,你实际上只是将它返回到连接池。

您可以使用 SqlConnection.ClearPool(connection) 或 SqlConnection.ClearAllPools 来实际关闭连接,但这会影响您网站的性能。

此外,您可以使用连接字符串参数 Pooling=false 禁用池。 还有 Max Pool Size(默认为 100),您可能希望将其设置为较小的数字。

这一切都可能有效,但我也建议您切换供应商....

【讨论】:

    【解决方案5】:

    如果您只从数据库中获取数据,那么创建某种缓存并不是很困难。但如果有完整的 CRUD,那么更好的解决方案是更换托管服务提供商。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-03-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-08-21
      • 1970-01-01
      • 2021-12-08
      相关资源
      最近更新 更多