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

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

Примечание.

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

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

Примечание.

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

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

Dim connectionString As String = "Data Source=MSSQL1;" & _  
    "Initial Catalog=AdventureWorks;Integrated Security=SSPI;" & _  
    "MultipleActiveResultSets=True"  
string connectionString = "Data Source=MSSQL1;" +
    "Initial Catalog=AdventureWorks;Integrated Security=SSPI;" +  
    "MultipleActiveResultSets=True";  

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

Dim connectionString As String = "Data Source=MSSQL1;" & _  
    "Initial Catalog=AdventureWorks;Integrated Security=SSPI;" & _  
    "MultipleActiveResultSets=False"  
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 (ADO.NET).

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

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

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

  • заданных параметров (например, ANSI_NULLS, DATE_FORMAT, LANGUAGE, TEXTSIZE);

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

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

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

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

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

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

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

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

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

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

Ожидается: (значение NULL).

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

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

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

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

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

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

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

См. также