【问题标题】:How do I avoid "sleeping" processes in MSSQL?如何避免 MSSQL 中的“休眠”进程?
【发布时间】:2017-05-29 13:31:00
【问题描述】:

目前,当我连接到我的 MSSQL 数据库、调用存储过程、获取一些数据时,我遇到了很多服务器进程(从 sp_who2 看到)的问题,即“休眠”而不是完成(被删除)然后关闭连接。

在 C#/.NET 中连接 MSSQL 数据库、调用存储过程、从存储过程(数据读取器)检索数据然后关闭连接的最佳方式是什么?

有没有办法关闭/处置,以便“休眠”进程被杀死?

这和我创建新的SqlConnections,一直打开和关闭有关系吗?

我的流程如下:

请求发生:

  1. 我创建了一个连接到我的 MSSQL 数据库的新 SqlConnection 实例。
  2. 我调用存储过程,检索数据并将其呈现给用户。
  3. 我用.Close(); 关闭连接
  4. 我为每个请求重复所有这些步骤。请求每 5-10 秒发生一次。 (有时慢,有时快)

对不起,如果这个问题缺少一些细节,但我希望这足以得到一些有用的答案。

谢谢!

【问题讨论】:

  • 这是预期的行为——连接被池化,并且其中的一些始终保持可用,以最大限度地减少设置物理连接的开销。关闭连接并没有真正关闭它,它只是让它再次可供池使用。你遇到的“问题”是什么?活动会话的数量实际上是在增加,还是您只是认为有问题,因为这些会话完全存在?您的一般用法是正确的,但不是显式调用.Close(),而是更喜欢using:即使面对异常也是安全的。
  • @JeroenMostert 我会将其作为答案发布,并添加指向有关主题 msdn.microsoft.com/en-us/library/8xx3tyca(v=vs.110).aspx的 msdn 文档的链接
  • 我的假设是错误的,当有很多“休眠”进程时,数据库变得越来越慢,而当我试图清除这些“休眠”进程时,数据库变得更快。这只是巧合吗?
  • 池连接将在几分钟未使用后物理关闭。将连接和命令包装在 using 块中,以便它们自动关闭和释放。
  • 应用程序是否使用集成安全性连接到数据库?检查上面链接上的“池碎片”部分。

标签: c# sql .net sql-server database


【解决方案1】:

您需要使用 SET XACT_ABORT ON 或添加一些客户端回滚代码

当发生客户端超时事件(例如 .net CommandTimeout)时,客户端会向 SQL Server 发送“ABORT”。 SQL Server 然后简单地放弃查询处理。没有事务回滚,没有锁被释放。

现在,连接返回到连接池,因此它不会在 SQL Server 上关闭。如果发生这种情况(通过 KILL 或客户端重新启动等),则事务+锁将被清除。请注意,sp_reset_connection 不会或不会清除它们,即使它被宣传这样做

来自中止的这些碎屑会阻塞其他进程。

让 SQL Server 在客户端超时(严格来说,ABORT 事件)时清除事务+锁的方法是使用 SET XACT_ABORT ON。

您可以验证这是在 SSMS 中打开 2 个查询窗口:

窗口 1:

在菜单 Query..Query Options 中设置超时 5 秒然后运行此

BEGIN TRAN
UPDATE sometable WITH (TABLOCKX) SET foo = foo WHERE 1 = 0;
WAITFOR DELAY '00:00:10' -- just has to be longer then timeout

窗口 2,这将永远等待(或超时)

SELECT * FROM sometable

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-11
    • 2016-08-07
    • 2017-03-31
    • 1970-01-01
    • 2020-06-19
    • 2018-08-24
    • 2013-10-21
    • 2012-04-07
    相关资源
    最近更新 更多