我有一个在 IIS 上运行的网络服务,其中包含连接到 SQL 服务器的类。大多数时候,我们可以使用以下代码连接 SQL 服务器。但是有一段时间我们无法连接到sql server。我们没有收到任何错误。这是源代码:
public SqlConnection DbConnectSql()
{
string str = "Server=xxxx\xxx;database=production;Timeout=60000;user id=sa;password=888*;";
_con = new SqlConnection(str);
if (_con.State == ConnectionState.Open)
_con.Close();
_con.Open();
return _con;
}
在执行 _con.Open();
期间我们没有收到任何响应。我们不明白为什么我们没有得到任何回应。我必须每 2 天重新启动 IIS 才能打开 SQL 连接。谁能告诉我为什么我必须重新启动 IIS 才能使用 _con.Open();
方法?
最佳答案
这是对 DbConnectSql
的两次调用的交错,这将 a) 以两个线程共享一个连接对象的使用结束,并且 b) 泄漏一个打开的连接对象:
//Thread 1
public SqlConnection DbConnectSql()
{
string str = ...;
_con = new SqlConnection(str);
if (_con.State == ConnectionState.Open)
_con.Close();
_con.Open();
//Thread 2
public SqlConnection DbConnectSql()
{
string str = ...;
//-->Look, thread 2 is overwriting _con-->
_con = new SqlConnection(str);
return _con;
}
if (_con.State == ConnectionState.Open)
_con.Close();
_con.Open();
return _con;
}
如果我们幸运,那么第一个调用者不会在第二个调用者开始调用Open
之前尝试使用连接对象 1。但是第一个调用者创建的连接已经打开,现在没有人引用它。
您会遇到错误,因为连接池(最终)会耗尽,因此 Open
调用会抛出异常。您看不到异常的原因无法从显示的代码中诊断出来。
您可能幸运地一次持续 2 天,因为这些连接符合垃圾收集的条件,因此最终将返回到连接池。
最好只共享连接 string 。在 using
语句中构造 SqlConnection
(和 SqlCommand
)对象,使它们在局部范围内保持良好的范围,并确保它们被整齐地清理。您不需要此DbConnectSql
函数。它弊大于利。
1如果一个调用者试图检索结果集而另一个调用者仍在检索结果集,则这里可能还有其他可能的错误。
关于c# - 需要重启IIS才能获取sql连接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50850791/