调用ExecuteNonQueryAsync取消查询时出现SqlException错误求助
取消长时间运行的SQL异步查询时出现双错误的原因
问题场景
- 执行异步SQL查询的代码:
Await cmd.ExecuteNonQueryAsync(Me.cts.Token) - 运行的SQL语句:
set nocount on; declare @ID int=0 WHILE @ID<400000 BEGIN SET @ID+=1 WAITFOR DELAY '00:00:01.000' END
点击Cancel按钮调用cts.Cancel()取消查询时,触发包含两个错误的SqlException:
- "A severe error occurred on the current command. The results, if any, should be discarded."(错误号0)
- "Operation cancelled by user."(错误号0)
已验证包含INSERT语句的其他查询取消时数据可正常写入,询问错误原因。
原因分析
这是SQL Server在处理通过客户端令牌取消无结果集的长时间空循环查询时的正常行为:
- 你的测试SQL是一个没有实际数据输出、仅靠
WAITFOR DELAY持续占用连接的空循环,当客户端发起取消请求时,SQL Server的连接层会先抛出一个通用的“严重错误”提示(错误号0),告知当前命令已失效,结果不可用。 - 紧接着会抛出明确的“用户取消操作”错误,这才是取消操作的核心提示。
- 而包含INSERT的查询在取消时,事务/数据写入的逻辑会优先完成状态同步,SQL Server会直接返回“用户取消”的明确错误,不会额外触发通用严重错误提示——因为这类查询存在实际的数据库状态变更,SQL Server会优先处理变更的收尾,再返回取消提示。
简单来说,空循环查询没有实际的数据库操作上下文,取消时连接层的错误提示会先于业务级取消提示抛出,导致你看到两个错误;而有实际数据操作的查询,取消逻辑会更聚焦于业务层面的终止提示。
内容的提问来源于stack exchange,提问作者Peter Rudo
相关产品推荐
相关产品推荐

