我正在尝试在命令超时后终止由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连接器对其进行测试,但是它们两者的行为均相同,因此我认为它是预期的行为,但不了解原因。还想问一下命令超时后是否有一种方法可以杀死查询。
答案 0 :(得分:0)
至少在Npgsql中,CommandTimeout是作为客户端套接字超时实现的:经过一定时间后,Npgsql只会在其一侧关闭网络套接字。这不会取消查询服务器端,它将继续运行。
您可以设置PostgreSQL statement_timeout
参数,使它杀死运行超过给定时间的查询。为了获得最佳结果,请将statement_timeout
设置为低于CommandTimeout的值-这将确保服务器超时发生在客户端超时之前,从而保留连接并将服务器超时作为常规异常发送给客户端。
另一种选择是通过调用NpgsqlCommand.Cancel()
手动触发客户端取消。您可以随时随地执行此操作(例如,当用户单击按钮时),但是与statement_timeout
相反,它显然仅在网络启动时才有效。