Убить запрос после команды тайм-аут - PullRequest
0 голосов
/ 28 апреля 2019

Я пытаюсь уничтожить запрос, вызванный командой ADO.NET в базе данных postgresql, после тайм-аута команды:

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

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

В дотнет-коде исключение тайм-аута генерируется правильно, но мне интересно, почему запрос, запускаемый функцией timout_test, все еще находится в активном состоянии. Если я выполню запрос ниже, то запрос, выполненный timeout_tets, будет указан как активный:

SELECT * FROM pg_stat_activity where state = 'active';

Пытался протестировать его с помощью разъемов devart и npgsql, но оба они ведут себя одинаково, поэтому я предполагаю, что он предназначен для поведения, но не понимаю причину. Также хотел спросить, есть ли способ убить запрос после тайм-аута команды.

1 Ответ

0 голосов
/ 29 апреля 2019

По крайней мере, в Npgsql CommandTimeout реализован как тайм-аут на стороне клиента: через некоторое время Npgsql просто закроет сетевой сокет на своей стороне.Это не отменяет запрос на стороне сервера, который будет продолжаться.

Вы можете установить параметр PostgreSQL statement_timeout, чтобы он убивал запросы, выполняемые более заданного периода времени.;для достижения наилучших результатов установите statement_timeout на значение, меньшее чем CommandTimeout - это обеспечит, что время ожидания сервера наступит до истечения времени ожидания клиента, сохраняя соединение и передавая время ожидания сервера клиенту как обычное исключение.

Другой вариант -вручную вызвать отмену от клиента, вызвав NpgsqlCommand.Cancel().Вы можете делать это в любое время (например, когда пользователь нажимает кнопку), но, в отличие от statement_timeout, очевидно, что оно будет работать только при работающей сети.

...