SQL Server如何处理超时请求?



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

该超时由ADO.NET强制执行。SQL Server不知道命令超时这样的事情。. net客户端将发送一个"注意"TDS命令。您可以使用SQL Profiler观察这种行为,因为它有一个"注意"事件。

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

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

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

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

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

用c#写你的清理,在catch(SqlException ex)块(测试超时)。

最新更新