Níveis de Isolamento

Quando um processo de aplicativo acessa dados, o nível de isolamento determina o grau em que esses dados são bloqueados ou isolados de outros processos simultâneos. O nível de isolamento está em vigor durante uma unidade de trabalho.

Portanto, o nível de isolamento de um processo de aplicativo é especificado:
  • O grau em que as linhas que são lidas ou atualizadas pelo aplicativo estão disponíveis para outros processos de aplicativos em execução simultânea.
  • O grau em que a atividade de atualização de outros processos de aplicativos em execução simultânea pode afetar o aplicativo.

O nível de isolamento para instruções SQL estáticas é especificado como um atributo de um pacote e aplica-se aos processos de aplicação que utilizam esse pacote. O nível de isolamento é especificado durante o processo de preparação do programa, configurando a opção de ligação ISOLAMENTO ou pré-compilação. Para instruções SQL dinâmicas, o nível de isolamento padrão é o nível de isolamento que foi especificado para o pacote enquanto a instrução era preparada. Use a instrução SET CURRENT ISOLATION para especificar um nível de isolamento diferente para instruções SQL dinâmicas que são emitidas dentro de uma sessão. Para mais informações, consulte Registro especial de ISOLAMENTO ATUAL. Para ambas instruções SQL estáticas e instruções SQL dinâmicas, o isolamento-cláusula em um select-statement sobrevoa tanto o registro especial (se configurado) quanto o valor da opção de ligação. Para obter mais informações, consulte Selecione-instrução.

Os níveis de isolamento são cumpridos por bloqueios, e o tipo de bloqueio que é usado limita ou impede o acesso aos dados por processos de aplicação simultâneos. Tabelas temporárias declaradas e suas linhas não podem ser bloqueadas porque só são acessíveis para o aplicativo que as declarou.

O gerenciador de banco de dados suporta três categorias gerais de bloqueios:
Compartilhar (S)
Sob um bloqueio S, os processos de aplicação simultânea são limitados a operações de leitura nos dados.
Atualização (u)
Sob um bloqueio U, os processos de aplicativos simultâneos são limitados a operações somente de leitura nos dados, se esses processos não declararem que podem atualizar uma linha. O gerenciador de banco de dados assume que o processo atualmente olhando para uma linha pode atualizá-lo.
Exclusivo (X)
Sob um bloqueio X, os processos de aplicativos simultâneos são impedidos de acessar os dados de qualquer maneira. Esse tipo de bloqueio não se aplica a processos de aplicativos com um nível de isolamento de leitura não comprometida (UR), que pode ler, mas não modificar os dados.
Independentemente do nível de isolamento, o gerenciador de banco de dados coloca bloqueios exclusivos em cada linha que é inserida, atualizada ou excluída. Assim, todos os níveis de isolamento garantem que qualquer linha que seja alterada por um processo de aplicativo durante uma unidade de trabalho não seja alterada por nenhum outro processo de aplicativo. O gerenciador de banco de dados libera o bloqueio exclusivo quando a unidade de trabalho é concluída.
O gerenciador de banco de dados suporta quatro níveis de isolamento.
Nota: Alguns servidores de banco de dados host suportam o nível de isolamento no commit (NC) . Em outros servidores de banco de dados, esse nível de isolamento comporta-se como o nível de isolamento de leitura não comprometido.
Nota: A questão de simultaneidade lost updates (LU) não é permitida por nenhum dos quatro níveis de isolamento do produto Db2® .

Segue uma descrição detalhada de cada nível de isolamento, em ordem decrescente de impacto no desempenho, mas em ordem crescente de cuidado necessário quando os dados são acessados ou atualizados.

Leitura repetível (RR)

O nível de isolamento repetível de leitura bloqueia todas as linhas que um aplicativo faz referência durante uma unidade de trabalho (UOW). Se um aplicativo emite uma instrução SELECT duas vezes dentro da mesma unidade de trabalho, o mesmo resultado é retornado a cada vez. No RR, não são possíveis atualizações perdidas, acesso a dados não confirmados, leituras não repetíveis e leituras fantasmas.

Sob o RR, um aplicativo pode recuperar e operar nas linhas quantas vezes for necessário até que o UOW seja concluído. No entanto, nenhum outro aplicativo pode atualizar, excluir ou inserir uma linha que afetaria o conjunto de resultados até que o UOW seja concluído. Os aplicativos em execução sob o nível de isolamento de RR não podem ver as alterações não confirmadas de outras aplicações. Esse nível de isolamento garante que todos os dados retornados permaneçam inalterados até o momento em que o aplicativo vê os dados, mesmo quando são usadas tabelas temporárias ou bloqueio de linhas.

Toda linha referenciada é bloqueada, não apenas as linhas que são recuperadas. Por exemplo, se você escanear 10000 linhas e aplicar predicados a elas, bloqueios são mantidos em todas as 10000 linhas, mesmo se, digamos, apenas 10 linhas se qualificarem. Outro aplicativo não pode inserir ou atualizar uma linha que seria adicionada à lista de linhas referenciadas por uma consulta se essa consulta fosse executada novamente. Esse aspecto do RR evita leituras fantasmas.

Como o RR pode adquirir um número considerável de bloqueios, esse número pode exceder os limites especificados pelos parâmetros de configuração do banco de dados locklist e maxlocks. Para evitar o escalonamento de bloqueios, o otimizador pode optar por adquirir um único bloqueio em nível de tabela para uma varredura de índice, se houver probabilidade de escalonamento de bloqueios. Se você não deseja bloqueio de nível de tabela, use o nível de isolamento de estabilidade de leitura.

Enquanto o servidor Db2 avalia as restrições referenciais, ele pode ocasionalmente atualizar o nível de isolamento usado nas varreduras da tabela estrangeira para RR. Essa atualização pode ocorrer independentemente do nível de isolamento que foi definido anteriormente pelo usuário. Devido a essa atualização do nível de isolamento, mais bloqueios podem ser mantidos até o momento do commit, o que aumenta a probabilidade de um deadlock ou de um lock timeout. Para evitar esses problemas, crie um índice que contenha apenas as colunas de chaves estrangeiras, as quais a varredura de integridade referencial pode usar em vez disso.

Estabilidade de leitura (RS)

O nível de isolamento read stability bloqueia apenas essas linhas que um aplicativo recupera durante uma unidade de trabalho. O RS garante que qualquer linha qualificada que seja lida durante um UOW não possa ser alterada por outros processos de aplicativos até que o UOW seja concluído. O RS também garante que qualquer alteração em uma linha feita por outro processo de aplicativo não possa ser lida até que a alteração seja confirmada por esse processo. No RS, o acesso a dados não comprometidos e leituras não repetitivas não é possível. No entanto, leituras fantasmas são possíveis. As leituras fantasmas também podem ser introduzidas por atualizações simultâneas para linhas onde o valor antigo não satisfazia a condição de pesquisa do aplicativo original mas o novo valor atualizado faz.

Por exemplo, uma linha phantom pode ocorrer na seguinte situação:
  1. Processo de aplicação P1 lê o conjunto de linhas n que satisfazem alguma condição de pesquisa.
  2. Processo de aplicação P2 em seguida, insere uma ou mais linhas que satisfazem a condição de pesquisa e comete aquelas novas inserções.
  3. P1 lê o conjunto de linhas novamente com a mesma condição de pesquisa e obtém as linhas originais e as linhas que foram inseridas por P2.

Em um ambiente Db2 pureScale®, um aplicativo que esteja sendo executado nesse nível de isolamento poderá rejeitar um valor de linha confirmado anteriormente se a linha for atualizada simultaneamente em um membro diferente. Para substituir esse comportamento, especifique a opção WAIT_FOR_OUTCOME .

Esse nível de isolamento garante que todos os dados retornados permaneçam inalterados até o momento em que o aplicativo vê os dados, mesmo quando são usadas tabelas temporárias ou bloqueio de linhas.

O nível de isolamento do RS proporciona tanto um alto grau de simultaneidade quanto uma visualização estável dos dados. Para isso, o otimizador garante que bloqueios de nível de tabela não sejam obtidos até que ocorra a escalação de bloqueios.

O nível de isolamento do RS é adequado para uma aplicação que:
  • Opera em um ambiente simultâneo.
  • Requer que as linhas de qualificação permaneçam estáveis durante uma unidade de trabalho.
  • Não emite a mesma consulta mais de uma vez durante uma unidade de trabalho.
  • Não exige o mesmo conjunto de resultados quando uma consulta é emitida mais de uma vez durante uma unidade de trabalho.

Estabilidade do cursor (CS)

O nível de isolamento de estabilidade do cursor bloqueia qualquer linha que seja acessada durante uma transação enquanto o cursor estiver posicionado nessa linha. Esse bloqueio permanece em vigor até que a próxima linha seja obtida ou a transação termine. No entanto, se algum dado na linha foi alterado, o bloqueio será mantido até que a mudança seja confirmada.

Sob esse nível de isolamento, nenhum outro aplicativo pode atualizar ou excluir uma linha enquanto um cursor atualizável estiver posicionado nessa linha. Em CS, o acesso aos dados não confirmados de outras aplicações não é possível. No entanto, leituras não repetíveis e leituras fantasmas são possíveis.

CS é o nível de isolamento padrão. Ele é adequado quando você deseja simultaneidade máxima e precisa ver apenas dados confirmados. As varreduras executadas sob esse nível de isolamento se comportam de acordo com o parâmetro de configuração cur_commit (Currently Committed).

Em um ambiente Db2 pureScale, um aplicativo executado nesse nível de isolamento pode retornar ou rejeitar um valor de linha confirmado anteriormente se a linha for atualizada simultaneamente em um membro diferente. A opção WAIT FOR OUTCOME da configuração de resolução de acesso simultânea pode ser usada para substituir esse comportamento.

Nota: sob a semântica atualmente confirmada introduzida na Versão 9.7, apenas dados confirmados são retornados, como era o caso anteriormente, mas agora os leitores não esperam que os atualizadores liberem bloqueios de linhas... Em vez disso, os leitores retornam dados baseados na versão atualmente confirmada, ou seja, dados anteriores ao início da operação de gravação.

Leitura não confirmada (UR)

O nível de isolamento de leitura não comprometida permite que um aplicativo acesse as alterações não confirmadas de outras transações. Além disso, UR não impede que outro aplicativo acesse uma linha que está sendo lida, a menos que esse aplicativo esteja tentando alterar ou soltar a tabela.

No UR, é possível o acesso a dados não comprometidos, leituras não repetíveis e leituras fantasmas. Esse nível de isolamento é adequado se uma das seguintes afirmações for verdadeira:
  • Você executa consultas em tabelas somente de leitura.
  • Você emite apenas instruções SELECT, e ver dados que foram confirmados por outros aplicativos não é um problema.
UR funciona de forma diferente para cursores de leitura e updatable.
  • Os cursores de leitura podem acessar a maior parte das alterações não confirmadas de outras transações.
  • Tabelas, visualizações e índices que estão sendo criados ou eliminados por outras transações não estão disponíveis enquanto a transação está processando. Quaisquer outras alterações por outras transações podem ser lidas antes de serem confirmadas ou revertidas. Os cursores atualizáveis que operam sob UR se comportam como se o nível de isolamento fosse CS.
Se um aplicativo de leitura não confirmado usa cursores ambíguos, ele pode usar o nível de isolamento do CS quando ele for executado. Os cursores ambíguos podem ser escalados para CS se o valor da opção BLOCKING no comando PREP ou BIND for UNAMBIG (o padrão). Aplique uma das seguintes ações para evitar esse escalonamento:
  • Modifique os cursores no programa de aplicação para ser inequívoco. Altere as instruções SELECT para incluir a cláusula FOR READ ONLY.
  • Deixe os cursores no programa do aplicativo como estão, para que permaneçam ambíguos. No entanto, pré-compile o programa ou vincule-o com as opções BLOCKING ALL e STATICREADONLY YES para permitir que os cursores ambíguos sejam tratados como somente leitura quando o programa for executado.

O ISOLATION LEVEL UR pode se comportar de forma diferente em tabelas organizadas por coluna e em tabelas organizadas por linha.

Comparação dos níveis de isolamento

A Tabela 1 resume os níveis de isolamento suportados.
Tabela 1. Comparação de níveis de isolamento
  UR CS RS RR
Um aplicativo pode ver alterações não confirmadas feitas por outros processos de aplicativos? Sim Não Não Não
Um aplicativo pode atualizar alterações não confirmadas feitas por outros processos de aplicativos? Não Não Não Não
A reexecução de uma declaração pode ser afetada por outros processos de aplicativos? 1 Sim Sim Sim 2
As linhas atualizadas podem ser atualizadas por outros processos de aplicação? 3 Não Não Não Não
As linhas atualizadas podem ser lidas por outros processos de aplicação que estejam em execução em um nível de isolamento diferente de UR? Não Não Não Não
As linhas atualizadas podem ser lidas por outros processos de aplicação que estão em execução no nível de isolamento UR? Sim Sim Sim Sim
As linhas acessadas podem ser atualizadas por outros processos de aplicação? 4 Sim Sim Não Não
As linhas acessadas podem ser lidas por outros processos de aplicação? Sim Sim Sim Sim
A linha atual pode ser atualizada ou excluída por outros processos de aplicação? 5 Veja a nota 6 Veja a nota 6 Não Não
Nota:
  1. O cenário a seguir é um exemplo de um fenômeno de leitura fantasma : A unidade de trabalho UW1 lê o conjunto de n linhas que satisfaz alguma condição de pesquisa. Unidade de trabalho UW2 insere uma ou mais linhas que satisfazem a mesma condição de pesquisa e, em seguida, comete. Então, se UW1 repetir a leitura com a mesma condição de pesquisa, ele verá um conjunto de resultados diferente. Ele vê as linhas que foram lidas originalmente mais as linhas que foram inseridas pela UW2.
  2. Se a sua credencial de controle de acesso baseado em etiqueta (LBAC) alterar entre as leituras, resultados para a segunda leitura podem ser diferentes porque você tem acesso a linhas diferentes.
  3. O nível de isolamento não oferece nenhuma proteção ao aplicativo se o aplicativo estiver tanto lendo de e escrevendo para uma tabela. Por exemplo, um aplicativo abre um cursor em uma tabela e, em seguida, faz uma operação de inserção, atualização ou exclusão na mesma tabela. O aplicativo pode ver dados inconsistentes quando mais linhas são buscadas a partir do cursor aberto.
  4. O cenário a seguir é um exemplo de um fenômeno de leitura não repetível : A unidade de trabalho UW1 lê uma linha. Unidade de trabalho UW2 modifica essa linha e comete. Então, se UW1 ler essa linha novamente, ele poderá ver um valor diferente.
  5. O cenário a seguir é um exemplo de um fenômeno de leitura suja : A unidade de trabalho UW1 modifica uma linha. Unidade de trabalho UW2 lê essa linha antes do UW1 commits. Então, se UW1 reverter as alterações, UW2 lerá os dados inexistentes.
  6. Sob UR ou CS, se o cursor não for atualizável, a linha atual poderá ser atualizada ou excluída por outros processos de aplicação em alguns casos. Por exemplo, o buffering pode fazer com que a linha atual no cliente seja diferente da linha atual no servidor. Além disso, quando a semântica atualmente comprometida é usada no CS, uma linha que está sendo lida pode ter atualizações não comprometidas pendentes. Nesse caso, a versão atualmente comprometida da linha é sempre devolvida ao aplicativo.

Resumo dos níveis de isolamento

Tabela 2 lista as questões de simultaneidade que estão associadas a diferentes níveis de isolamento.
Tabela 2. Resumo dos níveis de isolamento
Nível de isolamento Acesso a dados não confirmados Leituras não repetidas Leituras fantasmas
Leitura repetível (RR) Impossível Impossível Impossível
Estabilidade de leitura (RS) Impossível Impossível Possível
Estabilidade do cursor (CS) Impossível Possível Possível
Leitura não confirmada (UR) Possível Possível Possível
O nível de isolamento afeta não apenas o grau de isolamento entre os aplicativos, mas também as características de desempenho de um aplicativo individual. O desempenho é afetado porque os recursos de processamento e memória necessários para obter e liberar bloqueios variam de acordo com o nível de isolamento. O potencial de deadlocks também varia com o nível de isolamento. Tabela 3 fornece uma heurística simples para ajudá-lo a escolher um nível de isolamento inicial para a sua aplicação.
Tabela 3. Diretrizes para a escolha de um nível de isolamento
Tipo de aplicativo Alta estabilidade de dados necessária Alta estabilidade de dados não necessária
Transações de leitura/gravação RS CS
Transações somente leitura RR ou RS UR