命令超时后终止查询

时间:2019-04-27 23:48:43

标签: c# postgresql npgsql devart

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

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连接器对其进行测试,但是它们两者的行为均相同,因此我认为它是预期的行为,但不了解原因。还想问一下命令超时后是否有一种方法可以杀死查询。

1 个答案:

答案 0 :(得分:0)

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

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

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