【问题标题】:What does SQL Server do with a timed out request?SQL Server 如何处理超时请求?
【发布时间】:2013-05-16 14:03:33
【问题描述】:

假设我使用 C# 运行一个长时间运行的 SQL Server 存储过程(比如说 30 分钟)。进一步假设我在 C# 中的查询上设置了 1 小时的超时时间,这样无论出于何种原因,这个 SP 花费的时间比预期的要长,我最终不会垄断数据库。最后,假设这个存储过程中有一个 try/catch 块来捕获错误并在其中的任何步骤失败时进行一些清理。

一些代码(C#):

using (SqlCommand comm = new SqlCommand("longrunningstoredproc"))
{
    comm.Connection = conn;
    comm.CommandType = CommandType.StoredProcedure;
    comm.CommandTimeout = 3600;
    comm.ExecuteNonQuery();
}
/* Note: no transaction is used here, the transactions are inside the stored proc itself. */

T-SQL(基本上相当于以下):

BEGIN TRY
   -- initiailize by inserting some rows into a working table somewhere
   BEGIN TRANS
     -- do long running work
   COMMIT TRANS
   BEGIN TRANS
     -- do long running work
   COMMIT TRANS
   BEGIN TRANS
     -- do long running work
   COMMIT TRANS
   BEGIN TRANS
     -- do long running work
   COMMIT TRANS
   BEGIN TRANS
     -- do long running work
   COMMIT TRANS
   -- etc.

   -- remove the rows from the working table (and set another data point to success)
END TRY
BEGIN CATCH
   -- remove the rows from the working table (but don't set the other data point to success)
END CATCH

我的问题是,当命令从 C# 端超时时,SQL Server 将如何处理查询?它会调用 SP 的 catch 块,还是将其完全切断,以便我需要在 C# 代码中执行清理?

【问题讨论】:

  • 该命令不会从 C# 站点超时 - 数据库会超时。 C# 代码无法控制(它告诉数据库在 1 小时后超时,而数据库就是这样做的)。

标签: c# sql sql-server-2008


【解决方案1】:

超时由 ADO.NET 强制执行。 SQL Server 不知道命令超时之类的事情。 .NET 客户端将发送一个“注意”TDS 命令。您可以使用 SQL Profiler 观察此行为,因为它具有“注意”事件。

当 SQL Server 收到取消消息时,它将取消当前正在运行的查询(就像 SSMS 在您按下停止按钮时所做的那样)。它将中止批处理(就像在 SSMS 中一样)。这意味着无法运行任何捕获代码。连接将保持活动状态。

根据我的经验,事务将立即回滚。我不认为这是有保证的。

TL;DR:ADO.NET 中的超时行为与您在 SSMS 中按下停止键的行为相同(或称为 SqlCommand.Cancel)。

这是参考:https://techcommunity.microsoft.com/t5/sql-server-support/how-it-works-attention-attention-or-should-i-say-cancel-the/ba-p/315511

【讨论】:

    【解决方案2】:

    超时是连接上发生的事情,而不是正在运行的查询。

    这意味着您的BEGIN CATCH 在超时的情况下将不会执行,因为查询对此一无所知。

    用 C# 在 catch(SqlException ex) 块中编写您的清理工作(测试超时)。

    【讨论】:

      猜你喜欢
      • 2011-01-11
      • 1970-01-01
      • 2012-10-30
      • 1970-01-01
      • 2015-09-24
      • 1970-01-01
      • 1970-01-01
      • 2016-02-06
      相关资源
      最近更新 更多