【问题标题】:Does the SQL connection not get closed if you put the datareader in a using block?如果将数据读取器放在 using 块中,SQL 连接是否不会关闭?
【发布时间】:2013-07-30 15:48:48
【问题描述】:

所以,我最近继承了一个使用以下数据访问模式的大型项目;不幸的是,这导致了大量与连接池相关的超时异常。

超时。在获得一个之前的超时时间 来自池的连接。这可能是因为所有汇集的 正在使用连接并且已达到最大池大小”

很明显,连接正在泄漏并且没有正确关闭。 因此,框架有一个DataAccess 类,其方法为GetDataReader

当引用数据读取器时,它被放置在一个 using 块中,但连接仍在泄漏。

连接没有显式关闭或放置在 using 块中是连接泄漏的原因吗?

通常,我会将连接包装在 using 块中,并将数据读取器包装在 using 块中。

很明显,这个框架有很大的缺陷,但是使用数据读取器的选项CommandBehavior.CloseConnection 会以某种方式解决这个问题吗?

没有外部代码直接访问SqlConnection,必须通过这个DataAccess类。

public IDataReader GetDataReader(QueryDto dto)
{
    DateTime current = DateTime.Now;
    Database db = DatabaseFactory.CreateDatabase(dto.DatabaseName);

    DbCommand cmd = db.GetStoredProcCommand(dto.StoredProcedureName);

    if (dto.Params.Length > 0)
    {
        cmd = db.GetStoredProcCommand(dto.StoredProcedureName, dto.Params);
    }

    dto.Command = cmd;

    cmd.CommandTimeout = dto.Timeout;
    cmd.Connection = db.CreateConnection();

    try
    {
        cmd.Connection.Open();
    }
    catch (SqlException ex)
    {
        // Handle Exception here...
        throw;
    }

    return rdr;
}

在一些静态仓库类中的使用:

var query = new QueryDto
{
    DatabaseName = "SomeDatabase",
    Params = parms,
    StoredProcedureName = "StoredProcedureName"
};

using (IDataReader dr = dataAccess.GetDataReader(query))
{
    while (dr.Read())
    {
        // do stuff here
    }
}

【问题讨论】:

标签: sql-server ado.net connection-pooling datareader connection-timeout


【解决方案1】:

我认为您的问题是 using 语句围绕一个嵌入了开放资源的函数。 using 不会处理在GetDataReader 内打开的连接。我认为你是正确的,连接本身需要在 using 块中。 using statement 只对传入的对象调用 Dispose,而不是任何嵌套资源。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-16
    • 2012-01-21
    • 2010-09-08
    • 1970-01-01
    相关资源
    最近更新 更多