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

sya*_*ani 10 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. */
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

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

usr*_*usr 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-查询和待确定对过程的-results.aspx