Partilhar via


Habilitar vários conjuntos de resultados ativos

Vários conjuntos de resultados ativos (MARS) é um recurso que funciona com o SQL Server para permitir a execução de vários lotes em uma única conexão. Quando o MARS está habilitado para uso com o SQL Server, cada objeto de comando usado adiciona uma sessão à conexão.

Nota

Uma única sessão MARS abre uma conexão lógica para o MARS usar e, em seguida, uma conexão lógica para cada comando ativo.

Ativando e desativando o MARS na cadeia de conexão

Nota

As cadeias de conexão a seguir usam o banco de dados AdventureWorks de exemplo incluído no SQL Server. As cadeias de conexão fornecidas pressupõem que o banco de dados está instalado em um servidor chamado MSSQL1. Modifique a cadeia de conexão conforme necessário para seu ambiente.

O recurso MARS está desativado por padrão. Ele pode ser ativado adicionando o par de "MultipleActiveResultSets=True" palavras-chave à sua cadeia de conexão. "True" é o único valor válido para ativar o MARS. O exemplo a seguir demonstra como se conectar a uma instância do SQL Server e como especificar que o MARS deve ser habilitado.

Dim connectionString As String = "..." & _
    "MultipleActiveResultSets=True"
string connectionString = "..." +
    "MultipleActiveResultSets=True";

Você pode desativar o MARS adicionando o "MultipleActiveResultSets=False" par de palavras-chave à sua cadeia de conexão. "False" é o único valor válido para desativar o MARS.

Considerações especiais ao usar o MARS

Em geral, os aplicativos existentes não devem precisar de modificação para usar uma conexão habilitada para MARS. No entanto, se você deseja usar os recursos MARS em seus aplicativos, você deve entender as seguintes considerações especiais.

Declaração Intercalada

As operações MARS são executadas de forma síncrona no servidor. É permitida a intercalação de instruções SELECT e BULK INSERT. No entanto, as instruções DML (linguagem de manipulação de dados) e DDL (linguagem de definição de dados) são executadas atomicamente. Todas as instruções que tentam ser executadas enquanto um lote atômico está em execução são bloqueadas. A execução paralela no servidor não é um recurso MARS.

Se dois lotes forem enviados sob uma conexão MARS, um deles contendo uma instrução SELECT, o outro contendo uma instrução DML, o DML poderá iniciar a execução dentro da execução da instrução SELECT. No entanto, a instrução DML deve ser executada até a conclusão antes que a instrução SELECT possa progredir. Se ambas as instruções estiverem sendo executadas na mesma transação, quaisquer alterações feitas por uma instrução DML após a instrução SELECT ter iniciado a execução não serão visíveis para a operação de leitura.

Uma instrução WAITFOR dentro de uma instrução SELECT não produz a transação enquanto ela está aguardando, ou seja, até que a primeira linha seja produzida. Isso implica que nenhum outro lote pode ser executado dentro da mesma conexão enquanto uma instrução WAITFOR está aguardando.

Cache de sessão MARS

Quando uma conexão é aberta com o MARS habilitado, uma sessão lógica é criada, o que adiciona sobrecarga adicional. Para minimizar a sobrecarga e melhorar o desempenho, o SqlClient armazena em cache a sessão MARS em uma conexão. O cache contém no máximo 10 sessões MARS. Este valor não é ajustável pelo utilizador. Se o limite de sessão for atingido, uma nova sessão será criada — um erro não será gerado. O cache e as sessões contidas nele são por conexão; eles não são compartilhados entre conexões. Quando uma sessão é liberada, ela é retornada ao pool, a menos que o limite superior do pool tenha sido atingido. Se o pool de cache estiver cheio, a sessão será fechada. As sessões MARS não expiram. Eles só são limpos quando o objeto de conexão é descartado. O cache de sessão MARS não é pré-carregado. Ele é carregado à medida que o aplicativo requer mais sessões.

Segurança de Thread

As operações MARS não são thread-safe.

Conjunto de Ligações

As conexões habilitadas para MARS são agrupadas como qualquer outra conexão. Se um aplicativo abrir duas conexões, uma com o MARS habilitado e outra com o MARS desabilitado, as duas conexões estarão em pools separados. Para obter mais informações, consulte Pool de conexões do SQL Server (ADO.NET).

Ambiente de execução em lote do SQL Server

Quando uma conexão é aberta, um ambiente padrão é definido. Esse ambiente é então copiado para uma sessão lógica do MARS.

O ambiente de execução em lote inclui os seguintes componentes:

  • Definir opções (por exemplo, ANSI_NULLS, DATE_FORMAT, LANGUAGE, TEXTSIZE)

  • Contexto de segurança (função de usuário/aplicativo)

  • Contexto do banco de dados (banco de dados atual)

  • Variáveis de estado de execução (por exemplo, @@ERROR, @@ROWCOUNT @@FETCH_STATUS @@IDENTITY)

  • Tabelas temporárias de nível superior

Com o MARS, um ambiente de execução padrão é associado a uma conexão. Cada novo lote que começa a ser executado em uma determinada conexão recebe uma cópia do ambiente padrão. Sempre que o código é executado em um determinado lote, todas as alterações feitas no ambiente têm como escopo o lote específico. Quando a execução terminar, as configurações de execução serão copiadas para o ambiente padrão. No caso de um único lote emitir vários comandos a serem executados sequencialmente sob a mesma transação, a semântica é a mesma exposta por conexões envolvendo clientes ou servidores anteriores.

Execução paralela

O MARS não foi projetado para remover todos os requisitos para várias conexões em um aplicativo. Se um aplicativo precisar de uma verdadeira execução paralela de comandos em um servidor, várias conexões devem ser usadas.

Por exemplo, considere o seguinte cenário. Dois objetos de comando são criados, um para processar um conjunto de resultados e outro para atualizar dados; partilham uma ligação comum através do MARS. Neste cenário, o Transaction.Commit falha na atualização até que todos os resultados tenham sido lidos no primeiro objeto de comando, produzindo a seguinte exceção:

Mensagem: Contexto de transação em uso por outra sessão.

Fonte: Provedor de dados .NET SqlClient

Esperado: (nulo)

Recebido: System.Data.SqlClient.SqlException

Há três opções para lidar com esse cenário:

  1. Inicie a transação depois que o leitor for criado, para que ele não faça parte da transação. Cada atualização torna-se então a sua própria transação.

  2. Confirme todo o trabalho depois que o leitor for fechado. Isso tem potencial para um lote substancial de atualizações.

  3. Não utilize MARS; em vez disso, use uma conexão separada para cada objeto de comando, como faria antes do MARS.

Detetando o suporte a MARS

Um aplicativo pode verificar o suporte MARS lendo o SqlConnection.ServerVersion valor. O número principal deve ser 9 para SQL Server 2005 e 10 para SQL Server 2008.

Consulte também