SQL Server - qual nível de isolamento para instruções de seleção sem bloqueio?

9

Eu tenho uma transação de longa execução (chamada, digamos, T1) que executa algumas exclusões, atualizações e inserções em uma tabela no SQL Server 2008 R2. Ao mesmo tempo, outro processo executa periodicamente instruções de seleção desta tabela.

Nas configurações de isolamento padrão (READ COMMITTED, acho?), O T1 bloqueia a execução de quaisquer instruções de seleção até que a transação seja confirmada ou revertida.

O que eu gostaria de ver é que as instruções select funcionem com dados consistentes, mesmo enquanto a transação está em andamento. Acredito que o isolamento do INSTANTÂNEO pode ajudar, mas não tenho certeza se estou indo na direção certa. Esse seria o melhor nível de isolamento para este aplicativo?

Em segundo lugar, não tenho controle sobre o processo que está chamando as instruções select, mas tenho controle sobre o aplicativo .NET que chama T1. Seriam necessárias alterações no nível de isolamento tanto nas instruções de seleção quanto no T1, ou seria suficiente marcar apenas T1 como tendo um nível de isolamento diferente?

crescer
fonte

Respostas:

8

Em um mundo ideal, você teria duas opções, INSTANTÂNEO e INSTANTÂNEO LIDO COMPRIDO (RCSI). Certifique-se de entender o básico dos níveis de isolamento de transação antes de decidir qual é apropriado para sua carga de trabalho. Esteja ciente dos diferentes resultados que você pode ver como resultado da mudança para o RCSI.

Parece que não é um mundo ideal, pois você não tem controle sobre o aplicativo que está gerando as instruções select. Nesse caso, sua única opção é ativar o RCSI para o banco de dados em questão, de modo que os selecionados usem automaticamente o RCSI em vez de READ COMMITTED.

Mark Storey-Smith
fonte
6

Correto, use o isolamento SNAPSHOT para obter dados consistentes e confirmados antes do início da transação.

O isolamento READ UNCOMMITTED (também conhecido como dica NOLOCK) lerá dados sujos e inconsistentes

Quando você ativa o isolamento SNAPSHOT, ele entra em vigor para todos os SELECTs daqui para frente. Você executa ALTER DATABASEcom READ_COMMITTED_SNAPSHOT neste caso

Editar: link adicionado + citação de ALTER DATABASE (em negrito)

Ativa a opção Instantâneo confirmado por leitura no nível do banco de dados. Quando ativada, as instruções DML começam a gerar versões de linha, mesmo quando nenhuma transação usa o isolamento de captura instantânea. Depois que essa opção é ativada, as transações que especificam o nível de isolamento confirmado pela leitura usam o controle de versão da linha em vez do bloqueio. Quando uma transação é executada no nível de isolamento confirmado pela leitura, todas as instruções veem uma captura instantânea de dados como ela existe no início da instrução.

E usando o isolamento de instantâneo (em negrito)

A opção de banco de dados READ_COMMITTED_SNAPSHOT determina o comportamento do nível de isolamento READ COMMITTED padrão quando o isolamento de captura instantânea é ativado em um banco de dados. Se você não especificar explicitamente READ_COMMITTED_SNAPSHOT ON, READ COMMITTED será aplicado a todas as transações implícitas. Isso produz o mesmo comportamento da configuração READ_COMMITTED_SNAPSHOT OFF (o padrão). Quando READ_COMMITTED_SNAPSHOT OFF está em vigor, o Mecanismo de Banco de Dados usa bloqueios compartilhados para impor o nível de isolamento padrão. Se você definir a opção de banco de dados READ_COMMITTED_SNAPSHOT como ON, o mecanismo de banco de dados utilizará o controle de versão de linha e o instantâneo como padrão, em vez de usar bloqueios para proteger os dados.

Então sim.

A ativação do RCSI permitirá que as leituras obtenham dados consistentes e não sejam bloqueadas pelos gravadores que continuarão usando o Read Committed

gbn
fonte
4

Eu sugiro que você leia a seguinte pergunta e suas respostas: Problemas de bloqueio de banco de dados? .

Encontrar o nível de isolamento certo para usar no nível de banco de dados é a coisa mais rápida que você pode fazer agora para ajudar a corrigir esse problema, porque agora é difícil alterar todos os aplicativos que tocam no banco de dados e seu código. Como você disse "Não tenho nenhum controle sobre o processo que está chamando as instruções de seleção", a resposta mais rápida seria alternar o db para o nível de isolamento Read Snapshot Confirmado, para que você não toque nas consultas de leitura. Caso contrário, você precisará usar o nível de isolamento de instantâneo para as sessões que lêem dados durante suas grandes transações.

Mais detalhes aqui sobre como escolher o caminho certo: Escolhendo os níveis de isolamento baseados em controle de versão de linha .

Marian
fonte