Включение нескольких активных наборов результатов

Скачать ADO.NET

Multiple Active Result Sets (MARS) — это функция SQL Server, которая позволяет выполнять несколько пакетов в рамках одного соединения. Когда для работы с SQL Server включен режим MARS, каждый используемый объект команды добавляет сеанс к соединению.

Примечание.

Один сеанс режима MARS открывает одно логическое подключение для использования самим режимом MARS, а затем — по одному логическому подключению для каждой активной команды.

Включение и отключение режима MARS в строке подключения

Примечание.

В следующей строке подключения используется образец базы данных AdventureWorks, входящий в состав SQL Server. Приведенные здесь строки подключения предполагают, что база данных установлена на сервере MSSQL1. При необходимости измените строку подключения для вашей среды.

Функция MARS по умолчанию отключена. Ее можно включить, добавив пару ключевых слов MultipleActiveResultSets=True в строку подключения. "True" — единственное допустимое значение для включения режима MARS. В следующем примере демонстрируется, как подключиться к экземпляру SQL Server, а также как указать, что режим MARS должен быть включен.

string connectionString = "Data Source=MSSQL1;" +   
    "Initial Catalog=AdventureWorks;Integrated Security=SSPI;" +  
    "MultipleActiveResultSets=True";  

Отключить MARS можно, добавив в строку подключения пару ключевых слов "MultipleActiveResultSets=False". "False" — единственное допустимое значение для отключения режима MARS. В следующей строке подключения показано, как отключить режим MARS.

string connectionString = "Data Source=MSSQL1;" +   
    "Initial Catalog=AdventureWorks;Integrated Security=SSPI;" +  
    "MultipleActiveResultSets=False";  

Особые рекомендации при использовании режима MARS

Как правило, для использования подключения с включенным режимом MARS не требуется изменять существующие приложения. Тем не менее, если вы хотите использовать функции MARS в приложениях, следует учитывать следующие особенности.

Чередование инструкций

Операции режима MARS выполняются синхронно на сервере. Допускается переключение инструкций SELECT и BULK INSERT инструкций. Тем не менее, инструкции языка обработки данных DML и языка описания данных DDL выполняются атомарно. Попытка выполнения любых инструкций во время выполнения атомарного пакета блокируется. Параллельное выполнение на сервере не является функцией режима MARS.

Если в рамках подключения режима MARS отправляются два пакета (один с инструкцией SELECT, другой с инструкцией DML), выполнение инструкции DML может начаться во время выполнения инструкции SELECT. Тем не менее, выполнение инструкции SELECT можно продолжить только после полного выполнения инструкции DML. Если обе инструкции выполняются в рамках одной транзакции, любые изменения, внесенные инструкцией DML после начала выполнения инструкции SELECT, являются невидимыми для операции чтения.

Инструкция WAITFOR внутри инструкции SELECT не выдает транзакцию во время ожидания, то есть пока не будет сформирована первая строка. Это означает, что пока инструкция WAITFOR ждет, другие пакеты не могут выполняться в рамках одного подключения.

Кэш сеанса MARS

При открытии подключения с включенным режимом MARS создается логический сеанс, что создает дополнительную нагрузку. Чтобы свести к минимуму затраты и повысить производительность, SqlClient кэширует сеанс режима MARS в рамках соединения. Кэш может содержать максимум 10 сеансов режима MARS. Это значение не может быть изменено пользователем. При достижении лимита сеансов создается новый сеанс — ошибка не формируется. Сам кэш и содержащиеся в нем сеансы принадлежат одному подключению. Они не могут использоваться в нескольких подключениях. Когда сеанс освобождается, он возвращается в пул, если только не был достигнут верхний предел пула. Если пул кэша заполнен, то сеанс закрывается. Сеансы MARS не истекают. Они очищаются только при удалении объекта подключения. Кэш сеансов режима MARS предварительно не загружается. Он загружается, когда приложению требуется больше сеансов.

Потокобезопасность

Операции MARS не являются потокобезопасными.

Организация пулов соединений

Подключения с поддержкой MARS, как и любые другие подключения, объединяются в пул. Если приложение открывает два подключения (одно с включенным режимом MARS и другое, для которого режим MARS отключен), эти два подключения помещаются в отдельные пулы.

Среда выполнения пакетов SQL Server

При открытии подключения определяется среда по умолчанию. Затем эта среда копируется в логический сеанс MARS.

Среда пакетного выполнения состоит из следующих компонентов:

  • Задайте параметры (например, ANSI_NULLS, DATE_FORMAT, LANGUAGE, TEXTSIZE)

  • контекста безопасности (роль пользователя/приложения);

  • контекста базы данных (текущая база данных);

  • Переменные состояния выполнения (например, @@ERROR, @@ROWCOUNT, @@FETCH_STATUS @@IDENTITY)

  • Временные таблицы верхнего уровня

При работе в режиме MARS среда выполнения по умолчанию ассоциируется с подключением. Каждый новый пакет, выполняемый для конкретного соединения, получает копию среды по умолчанию. Каждый раз, когда код выполняется в рамках заданного батча, все изменения, внесённые в среду, ограничиваются рамками этого батча. Как только выполнение завершается, настройки выполнения копируются в среду по умолчанию. Если один пакет выдает несколько команд для последовательного выполнения в рамках одной транзакции, семантика такая же, как и при подключениях прошлых клиентов или серверов.

Параллельное выполнение

MARS не предназначен для устранения всех случаев необходимости в нескольких подключениях в приложении. Если приложению требуется настоящее параллельное выполнение команд для сервера, следует использовать несколько подключений.

Рассмотрим следующий сценарий. Создаются два командных объекта: один для обработки набора результатов, а другой — для обновления данных; они используют общее подключение через MARS. В этом сценарии Transaction. Commit не сможет выполнить обновление, пока не будут прочитаны все результаты для первого объекта команды, при этом выдается следующее исключение:

Сообщение: контекст транзакции используется другим сеансом.

Источник: поставщик данных Microsoft SqlClient

Ожидается: (null)

Получено: Microsoft.Data.SqlClient.SqlException

Есть три способа обработки этой ситуации.

  • Запустите транзакцию после создания считывателя, чтобы считыватель не был частью транзакции. После этого любое обновление будет становиться собственной транзакцией.

  • Зафиксировать всю работу после закрытия модуля чтения. Это создает потенциал для значительного пакета обновлений.

  • Не использовать режим MARS. Вместо этого использовать отдельное подключение для каждого объекта команды, что было стандартным решением до появления режима MARS.

Обнаружение поддержки MARS

Приложение может проверить наличие поддержки MARS, прочитав значение SqlConnection.ServerVersion. Основным номером должен быть 9 для SQL Server 2005 и 10 для SQL Server 2008.