假设我使用 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
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)