ExecuteNonQuery使处于睡眠状态的等待命令会话



我有一个用C#编写的命令行实用程序,它更新数据库中的一些记录,然后进入一个检查其他内容的循环。出于某种原因,SQL执行后,SQL server 2008中的SQL执行总是留下一个正在等待的命令会话。我可以使用SQL server活动监视器并运行sp_who2来确认这一点。但SQL事务确实已成功提交。我可以从代码中的调试和数据库中数据记录的时间戳中看出这一点。此外,当我明确停止命令行实用程序时,打开的睡眠会话将被终止。这表明我的函数创建了一些SQL连接对象,在应用程序中止时CLR对其进行垃圾收集之前,这些对象无法处理。这怎么会发生?谢谢这是代码:

bool result = false;
using (SqlConnection conn = new SqlConnection(this.Connection))
{
    using (SqlCommand cmd = conn.CreateCommand())
    {
        cmd.CommandText =
                @"if not exists (select id from pl where sj=@sj and ej=@ej and dateInactivated is null) 
                    insert into pl(sj,ej,pf, br, tk, lastModified )
                    values(@sj,@ej,@pf,@br,@tk,getDate())
                else
                    update pl set sj=@sj,ej=@ej,pf=@pf,br=@br,tk=@tk,lastModified=getDate()
                    where sj=@sj and ej=@ej and dateInactivated is null
                ";
        cmd.Parameters.AddWithValue("@sj", sj);
        cmd.Parameters.AddWithValue("@ej", ej);
        cmd.Parameters.AddWithValue("@pf", pf);
        cmd.Parameters.AddWithValue("@br", br);
        cmd.Parameters.AddWithValue("@tk", tkData);
        cmd.CommandTimeout = 60;
        SqlTransaction trans = null;
        try
        {
            conn.Open();
            trans = conn.BeginTransaction();
            cmd.Transaction = trans;
            cmd.ExecuteNonQuery();
            trans.Commit();
            conn.Close();
            result = true;
        }
        catch (SqlException ex)
        {
            if (trans != null)
            {
                trans.Rollback();
            }
            Log.WriteLog(LogLevel.ERROR, ex.Message);
            result = false;
        }
        finally
        {
            if (conn.State != ConnectionState.Closed)
            {
                conn.Close();
            }
        }
    }
}
return result;

注意,tk字段是xml数据库字段。

这被称为连接池,您希望它以这种方式工作。

基本上,完全放弃连接,然后为应用程序重新建立连接,会比重新使用先前调用代码留下的空闲连接带来更高的惩罚。这是一件好事。

这是由于池。99.99%的情况下,这是一件很棒的事情——它可以减少建立和断开的连接,如果多线程,则可以减少同时打开的连接。

如果将Pooling=false添加到连接字符串中,则不会使用它。这样做的唯一原因是:

  1. 作为一种临时措施,如果您在某个地方泄漏了池连接,请注意,就性能而言,这会使糟糕的情况变得更糟,但不会达到最大池大小。此处重点强调临时
  2. 客户端应用程序共享数据库,并在很短的时间内使用连接。在这里,您需要关闭池,因为它虽然降低了每个客户端的效率,但也减轻了服务器本身的压力

第二种非常罕见。第一种应该非常罕见——再次强调临时

最新更新