SQL Server对超时请求执行什么操作?

时间:2013-05-16 14:03:33

标签: c# sql sql-server-2008

假设我使用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#代码中执行清理?

2 个答案:

答案 0 :(得分:5)

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

当SQL Server收到取消时,它将取消当前运行的查询(就像按下停止按钮时SSMS一样)。它将中止批处理(就像在SSMS中一样)。这意味着不能运行任何catch代码。连接将保持活跃。

根据我的经验,交易将立即回滚。我不认为这是有保障的。

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

以下是对此的引用:http://blogs.msdn.com/b/psssql/archive/2008/07/23/how-it-works-attention-attention-or-should-i-say-cancel-the-query-and-be-sure-to-process-your-results.aspx

答案 1 :(得分:3)

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

这意味着您的BEGIN CATCH将在超时时不会执行,因为查询不知道它。

catch(SqlException ex)块中的C#中编写清理(测试超时)。