需要重新启动IIS才能获得sql连接

时间:2018-06-14 06:18:03

标签: c# sql-server iis

我有一个在IIS上运行的web服务,它包含连接到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();方法?

1 个答案:

答案 0 :(得分:1)

这里是对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 。在SqlConnection语句中构造SqlCommand(和using)对象,使它们在本地范围内保持良好状态,并确保它们得到整齐清理。您不需要此DbConnectSql功能。它弊大于利。

1 此处可能存在其他可能的错误,如果一个调用者尝试检索结果集,而另一个调用者仍在检索结果集。