命令超时后终止查询

Kill query after command timout

我试图在命令超时后终止由 ADO.NET 命令在 postgresql 数据库上触发的查询:

using (var command = new PgSqlCommand("public.timeout_test", connection))
{
    command.CommandTimeout = 10; 
    command.CommandType = CommandType.StoredProcedure;

    connection.Open();
    command.ExecuteNonQuery();
}

在 dotnet 代码超时异常被正确抛出,但我想知道为什么 timout_test 函数触发的查询仍处于活动状态。如果我 运行 下面的查询,则 timeout_tets 执行的查询被列为活动的:

SELECT * FROM pg_stat_activity where state = 'active';

尝试使用 devart 和 npgsql 连接器对其进行测试,但它们的行为方式相同,因此我认为这是预期的行为,但不明白原因。还想问问有没有办法在命令超时后终止查询。

至少在 Npgsql 中,CommandTimeout 被实现为客户端套接字超时:在一定时间后,Npgsql 将简单地关闭其端的网络套接字。这不会取消查询服务器端,它将继续运行。

您可以设置 PostgreSQL statement_timeout 参数,让它终止查询 运行 超过给定的时间;为获得最佳结果,请将 statement_timeout 设置为低于 CommandTimeout 的值 - 这将确保服务器超时发生在客户端超时之前,保留连接并将服务器超时作为常规异常传输到客户端。

另一种选择是通过调用 NpgsqlCommand.Cancel() 从客户端手动触发取消。您可以随时执行此操作(例如,当用户单击按钮时),但与 statement_timeout 相反,它显然只有在网络正常时才有效。