Что происходит при отмене запроса к базе данных с использованием CancellationToken?

«Что происходит при отмене запроса к базе данных с использованием CancellationToken?» — вопрос из категории Сети, который задают на 25% собеседований C# Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Когда запрос к БД отменяется через CancellationToken, поведение зависит от драйвера базы данных (поставщика данных). В современных драйверах (например, Microsoft.Data.SqlClient для SQL Server) это приводит к попытке отменить выполнение команды на самом сервере БД.

Типичный сценарий:

  1. Драйвер отправляет специальный TDS-пакет (Tabular Data Stream) для отмены выполнения текущей команды на SQL Server.
  2. Сервер БД пытается прервать выполнение запроса. Это не всегда мгновенно, особенно для сложных операций.
  3. На стороне кода приложения выбрасывается исключение (например, SqlException с определенным кодом ошибки).

Пример кода:

using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(5)); // Таймаут 5 сек.
try
{
    var result = await connection.QueryAsync<MyEntity>(
        "SELECT * FROM LargeTable",
        cancellationToken: cts.Token // Токен передается в драйвер
    );
}
catch (SqlException ex) when (ex.Number == 3980) // Код ошибки "Operation cancelled"
{
    // Запрос был отменен
    _logger.LogWarning("Запрос к БД был отменен.");
}

Важные нюансы:

  • Не мгновенно: Отмена на сервере БД — это запрос, а не команда. Длительная транзакция может завершиться раньше, чем будет обработан сигнал отмены.
  • Поддержка драйверов: Не все драйверы или старые версии поддерживают корректную отмену. Всегда проверяйте документацию.
  • Соединение: Само подключение к БД обычно не разрывается и может использоваться для последующих запросов.