最近几天,我们经常在网站上看到这样的错误信息:

“超时过期。超时时间 在获取 来自池的连接。这可能 已经发生是因为全部池化了吗 连接正在使用,马克斯泳池 规模达到了。”

我们已经有一段时间没有更改代码中的任何内容了。我修改了代码以检查未关闭的打开连接,但发现一切正常。

我怎么解决这个问题? 我需要编辑这个池吗? 如何编辑此池的最大连接数? 高流量网站的推荐值是多少?


更新:

我需要在IIS中编辑一些东西吗?

更新:

我发现活动连接的数量在15到31之间,我发现在SQL server中配置的最大允许连接数超过3200个连接,是31太多了还是我应该在ASP中编辑一些东西。网络配置?


当前回答

在我的例子中,我没有关闭DataReader对象。

using (SqlCommand dbCmd = new SqlCommand("*StoredProcedureName*"))
using (dbCmd.Connection = new SqlConnection(WebConfigurationAccess.ConnectionString))
{
    dbCmd.CommandType = CommandType.StoredProcedure;

    //Add parametres
    dbCmd.Parameters.Add(new SqlParameter("@ID", SqlDbType.Int)).Value = ID;

    .....
    .....

    dbCmd.Connection.Open();
    var dr = dbCmd.ExecuteReader(); //created a Data reader here
    dr.Close();    //gotta close the data reader
    //dbCmd.Connection.Close(); //don't need this as 'using' statement should take care of this in its implicit dispose method.
}

其他回答

您可以通过在连接字符串中指定MinPoolSize=xyz和/或MaxPoolSize=xyz来指定最小和最大池大小。然而,这个问题的原因可能是另一回事。

这个问题,我在我的代码。我将粘贴一些示例代码,我已经来到下面的错误。 从池中获取连接之前的超时时间。这可能是因为所有池连接都在使用中,且池大小已达到最大。

 String query = "insert into STATION2(ID,CITY,STATE,LAT_N,LONG_W) values('" + a1 + "','" + b1 + "','" + c1 + "','" + d1 + "','" + f1 + "')";
    //,'" + d1 + "','" + f1 + "','" + g1 + "'

    SqlConnection con = new SqlConnection(mycon);
    con.Open();
    SqlCommand cmd = new SqlCommand();
    cmd.CommandText = query;
    cmd.Connection = con;
    cmd.ExecuteNonQuery();
    **con.Close();**

您希望每次都关闭连接。在此之前,我没有我们关闭连接,由于这个我得到了错误。 添加结束语句后,我已经克服了这个错误

除了公布的解决方案。

在处理1000页遗留代码时,每个代码都多次调用公共GetRS,这里有另一种解决问题的方法:

在现有的公共DLL中,我们添加了CommandBehavior。CloseConnection选择:

static public IDataReader GetRS(String Sql)
{
    SqlConnection dbconn = new SqlConnection(DB.GetDBConn());
    dbconn.Open();
    SqlCommand cmd = new SqlCommand(Sql, dbconn);
    return cmd.ExecuteReader(CommandBehavior.CloseConnection);   
}

然后,在每个页面中,只要关闭数据读取器,连接也会自动关闭,从而防止连接泄漏。

IDataReader rs = CommonDLL.GetRS("select * from table");
while (rs.Read())
{
    // do something
}
rs.Close();   // this also closes the connection

在我的例子中还发生了另一个原因,因为使用async/await,导致了相同的错误消息:

系统。InvalidOperationException: '超时。从池中获取连接之前的超时时间。这可能是因为所有池连接都在使用中,且池大小已达到最大。”

只是对发生了什么(以及我是如何解决它的)的一个快速概述,希望这将在未来帮助其他人:

找出原因

这一切都发生在ASP中。NET Core 3.1 web项目与Dapper和SQL Server,但我认为它是独立于这种类型的项目。

首先,我有一个中心函数给我SQL连接:

internal async Task<DbConnection> GetConnection()
{
    var r = new SqlConnection(GetConnectionString());
    await r.OpenAsync().ConfigureAwait(false);
    return r;
}

我在几十个方法中使用这个函数,例如:

public async Task<List<EmployeeDbModel>> GetAll()
{
    await using var conn = await GetConnection();
    var sql = @"SELECT * FROM Employee";

    var result = await conn.QueryAsync<EmployeeDbModel>(sql);
    return result.ToList();
}

正如您所看到的,我使用的是没有花括号({,})的new using语句,因此连接的处理是在函数的末尾完成的。

尽管如此,我还是得到了关于池中没有更多可用连接的错误。

我开始调试我的应用程序,并让它在异常发生时停止。当它停止时,我首先看了一下调用堆栈窗口,但这只显示了System.Data中的某个位置。SqlClient,并不是真正的帮助我:

接下来,我看了看Tasks窗口,这是一个更好的帮助:

在“等待”或“计划”状态下,对我自己的GetConnection方法的调用确实有数千次。

当在任务窗口中双击这样的一行时,它通过调用堆栈窗口向我显示了我的代码中的相关位置。

这帮助我找到了这种行为的真正原因。它在下面的代码中(只是为了完整性):

[Route(nameof(LoadEmployees))]
public async Task<IActionResult> LoadEmployees(
    DataSourceLoadOptions loadOption)
{
    var data = await CentralDbRepository.EmployeeRepository.GetAll();

    var list =
        data.Select(async d =>
            {
                var values = await CentralDbRepository.EmployeeRepository.GetAllValuesForEmployee(d);
                return await d.ConvertToListItemViewModel(
                    values,
                    Config,
                    CentralDbRepository);
            })
            .ToListAsync();
    return Json(DataSourceLoader.Load(await list, loadOption));
}

在上面的控制器操作中,我首先调用EmployeeRepository.GetAll()从数据库表“Employee”中获得模型列表。

然后,对于每个返回的模型(即结果集的每一行),我再次对employeerepository . getallvaluesforeemployee (d)进行数据库调用。

虽然这在性能方面非常糟糕,但在异步上下环境中,它的行为方式是占用连接池连接而不适当地释放它们。

解决方案

我通过在外部SQL查询的内部循环中删除SQL查询来解决这个问题。

这应该通过完全省略它来完成,或者如果需要,将它移动到外部SQL查询中的一个/多个lpe join,以便在一个SQL查询中获得数据库中的所有数据。

吸取的教训

不要在短时间内执行大量SQL查询,特别是在使用async/await时。

我也面临着同样的问题,经过几个小时的研究,我意识到我是在没有VPN的Guest网络上连接的,所以设置VPN对我来说很管用