我有以下代码
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";
}
问题是:如果var connection
括号(using
)之间发生意外错误,{ }
是否仍会关闭?
问题是我对存储过程的大多数调用是以这种方式进行的,最近我收到了这个错误:
System.InvalidOperationException:超时已过期。超时 从池中获取连接之前经过的时间段。这个 可能已经发生,因为所有汇集的连接都在使用中并且最大 达到了游泳池的大小。
我访问数据库的另一种方式是通过nHibernate。
答案 0 :(得分:4)
using语句确保即使调用Dispose也会调用 在对象上调用方法时发生异常。您可以 通过将对象放在try块中来实现相同的结果 然后在finally块中调用Dispose;其实这是怎么回事 using语句由编译器翻译。代码示例 之前在编译时扩展为以下代码(请注意额外的 花括号来创建对象的有限范围):
答案 1 :(得分:3)
是的,如果它进入using
语句的主体,它将被置于最后...是否正常到达块的末尾,通过返回语句退出,或者异常是抛出。基本上using
语句相当于try
/ finally
块。
这是仅的地方,您获得了连接吗?你的存储过程是否在某个地方陷入僵局,或许,就客户端代码而言,许多连接真正“忙”?
答案 2 :(得分:1)
就连接池用完可用连接而言,如果您处于分布式环境中并使用许多应用程序访问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;
}
答案 3 :(得分:0)
替换上面的代码......然后再次检查..
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";
}
答案 4 :(得分:0)
以下是参考资料:
http://msdn.microsoft.com/en-us/library/yh598w02(v=vs.80).aspx
我所知道的是,如果你在using {}子句中使用一个对象,那么该对象继承了IDisposable接口(即SqlConnection继承了DbConnection,而DbConnection继承了IDisposable),这意味着如果你得到一个异常,任何对象都将是关闭并妥善处理。