繁体   English   中英

使用(var connection = new SqlConnection(“ ConnectionString”))是否仍会关闭/将连接置于错误状态?

[英]Does using (var connection = new SqlConnection(“ConnectionString”)) still close/dispose the connection on error?

我有以下代码

try
{
    using (var connection = new SqlConnection(Utils.ConnectionString))
    {
        connection.Open();

        using (var cmd = new SqlCommand("StoredProcedure", connection))
        {                            
            cmd.CommandType = System.Data.CommandType.StoredProcedure;
            var sqlParam = new SqlParameter("id_document", idDocument);
            cmd.Parameters.Add(sqlParam);

            int result = cmd.ExecuteNonQuery();
            if (result != -1)
                return "something";

            //do something here

            return "something else";
        }
    }

    //do something
}
catch (SqlException ex)
{
    return "something AKA didn't work";
}

问题是:如果using方括号( { } )之间发生意外错误, var connection是否仍会关闭?

问题是我对存储过程的大多数调用都是以这种方式进行的,最近我一直收到此错误:

System.InvalidOperationException:超时已过期。 从池中获取连接之前已经过超时时间。 这可能是因为所有池化连接都在使用中,并且达到了最大池大小。

我访问数据库的另一种方法是通过nHibernate。

使用语句(C#参考)

using语句确保即使在调用对象的方法时发生异常,也将调用Dispose。 通过将对象放在try块中,然后在finally块中调用Dispose,可以达到相同的结果。 实际上,这就是编译器翻译using语句的方式。 前面的代码示例在编译时扩展为以下代码(请注意,额外的花括号可创建对象的有限作用域):

是的,如果它进入了using语句的主体,它将被放置在末尾……无论您是正常到达块的末尾,通过return语句退出还是引发异常。 基本上, using语句等效于try / finally块。

那是您获得联系的唯一地方吗? 您的存储过程是否已陷入某个地方的僵局,就客户端代码而言,确实使许多连接真正“忙”起来了吗?

就连接池用尽可用连接而言,如果您处于分布式环境中并且使用许多应用程序访问SQL Server,但是它们都使用相同的连接字符串,则它们都将在服务器上使用相同的池。 为了解决这个问题,您可以通过将连接WorkstationID设置为Environment.MachineName来更改每个应用程序的连接字符串。 这将使服务器将每个连接视为不同,并为每个计算机提供一个池,而不是共享池。

在下面的示例中,我们甚至传递令牌以允许同一台计算机上的应用程序具有多个池。

例:

    private string GetConnectionStringWithWorkStationId(string connectionString, string connectionPoolToken)
    {
        if (string.IsNullOrEmpty(machineName)) machineName = Environment.MachineName;

        SqlConnectionStringBuilder cnbdlr;
        try
        {
            cnbdlr = new SqlConnectionStringBuilder(connectionString);
        }
        catch
        {
            throw new ArgumentException("connection string was an invalid format");
        }

        cnbdlr.WorkstationID = machineName + connectionPoolToken;

        return cnbdlr.ConnectionString;
    }

这里是参考:

http://msdn.microsoft.com/zh-CN/library/yh598w02(v=vs.80).aspx

我所知道的是,如果在using {}子句中使用对象,则该对象会继承IDisposable接口(即SqlConnection继承DbConnection,而DbConnection继承IDisposable),这意味着如果您遇到异常,则任何对象都将被关闭并处置。正确地。

替换上面的代码..然后再次检查。

try
{
    using (var connection = new SqlConnection(Utils.ConnectionString))
    {
        connection.Open();
        using (var cmd = new SqlCommand("StoredProcedure", connection))
        {                            
            cmd.CommandType = System.Data.CommandType.StoredProcedure;
            var sqlParam = new SqlParameter("id_document", idDocument);
            cmd.Parameters.Add(sqlParam);

            int result = cmd.ExecuteNonQuery();
            if (result != -1)
                return "something";

            //do something here

            return "something else";

        }

        connection.Close();
        connection.Dispose();
    }

    //do something

}
catch (SqlException ex)
{
    return "something AKA didn't work";
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM