2.1 Leitura não confirmada

O "nível de isolamento da transação" refere-se ao grau de proteção fornecido pelos mecanismos internos do DBMS (ou seja, não requer programação especial) de todos ou alguns dos tipos de inconsistências de dados acima que ocorrem durante a execução paralela de transações. O padrão SQL-92 define uma escala de quatro níveis de isolamento:

  • Ler não confirmado
  • Ler confirmado
  • Leitura repetível
  • serializável

O primeiro deles é o mais fraco, o último é o mais forte, cada um subsequente inclui todos os anteriores.

O nível de isolamento mais baixo (primeiro). Se várias transações paralelas tentarem modificar a mesma linha da tabela, a linha final terá um valor determinado por todo o conjunto de transações concluídas com sucesso. Nesse caso, é possível ler não apenas dados logicamente inconsistentes, mas também dados cujas alterações ainda não foram registradas.

Uma maneira típica de implementar esse nível de isolamento é bloquear os dados enquanto o comando de alteração está sendo executado, o que garante que os comandos de modificação nas mesmas linhas executados em paralelo sejam realmente executados sequencialmente e nenhuma das alterações seja perdida. As transações somente leitura nunca são bloqueadas nesse nível de isolamento.

2.2 Ler confirmado

A maioria dos DBMS industriais, em particular Microsoft SQL Server, PostgreSQL e Oracle, usa esse nível por padrão. Nesse nível, é fornecida proteção contra rascunho, leitura “suja”, porém, durante a operação de uma transação, outra pode ser concluída com sucesso e as alterações feitas por ela são corrigidas. Como resultado, a primeira transação funcionará com um conjunto de dados diferente.

A implementação de uma leitura completa pode ser baseada em uma das duas abordagens: bloqueio ou controle de versão.

Bloqueio de dados legíveis e mutáveis.

Consiste no fato de que a transação de escrita bloqueia dados mutáveis ​​para transações de leitura operando no nível de commit de leitura ou superior até que seja concluída, impedindo assim a leitura "suja", e os dados bloqueados pela transação de leitura são liberados imediatamente após a conclusão da operação SELECT(assim, uma situação de "leitura não repetível" pode ocorrer em um determinado nível de isolamento).

Salvando várias versões de linhas que mudam em paralelo.

Cada vez que uma linha é alterada, o SGBD cria uma nova versão dessa linha, com a qual a transação que alterou os dados continua funcionando, enquanto qualquer outra transação de “leitura” retorna a última versão confirmada. A vantagem dessa abordagem é que ela é mais rápida porque evita o bloqueio. No entanto, requer, em comparação com o primeiro, um consumo significativamente maior de RAM, que é gasto no armazenamento de versões de linha.

Além disso, quando várias transações alteram dados em paralelo, pode criar uma situação em que várias transações simultâneas fazem alterações inconsistentes nos mesmos dados (como não há bloqueios, nada impedirá que isso aconteça). Em seguida, a transação que confirmar primeiro salvará suas alterações no banco de dados principal e as transações paralelas restantes serão impossíveis de confirmar (pois isso levará à perda da atualização da primeira transação). A única coisa que o DBMS pode fazer em tal situação é reverter o restante das transações e emitir uma mensagem de erro “O registro já foi alterado”.

Um método de implementação específico é escolhido pelos desenvolvedores do DBMS e, em alguns casos, pode ser personalizado. Portanto, por padrão, o MS SQL usa bloqueios, mas (na versão 2005 e superior) ao definir o READ_COMMITTED_SNAPSHOTparâmetro do banco de dados, ele muda para a estratégia de versionamento, o Oracle inicialmente funciona apenas de acordo com o esquema versionado. No Informix, você pode evitar conflitos entre transações de leitura e gravação definindo uma opção de configuração USELASTCOMMITTED(a partir da versão 11.1) que faz com que a transação de leitura receba os últimos dados confirmados.

2.3 Leitura repetível

O nível no qual uma transação de leitura "não vê" muda para os dados que leu anteriormente. Ao mesmo tempo, nenhuma outra transação pode alterar os dados lidos pela transação atual até que ela termine.

Os bloqueios no modo compartilhado são aplicados a todos os dados lidos por qualquer instrução em uma transação e são mantidos até que a transação seja concluída. Isso evita que outras transações modifiquem as linhas que foram lidas pela transação pendente. No entanto, outras transações podem inserir novas linhas que correspondam às condições de pesquisa das instruções contidas na transação atual. Quando a instrução for reiniciada pela transação atual, novas linhas serão buscadas, resultando em uma leitura fantasma.

Dado que os bloqueios compartilhados são mantidos até o final da transação, em vez de serem liberados no final de cada instrução, o grau de simultaneidade é menor do que o nível de isolamento READ COMMITTED. Portanto, geralmente não é recomendado usar este e níveis de transação mais altos desnecessariamente.

2.4 Serializável

O mais alto nível de isolamento; as transações são completamente isoladas umas das outras, cada uma é executada como se não houvesse transações paralelas. É somente nesse nível que as transações simultâneas não estão sujeitas ao efeito de "leitura fantasma".

2.5 Suporte para isolamento de transação em DBMS real

O DBMS transacional nem sempre suporta todos os quatro níveis e também pode introduzir níveis adicionais. Existem também várias nuances no fornecimento de isolamento.

Portanto, a princípio, o Oracle não suporta o nível zero, pois sua implementação de transações exclui “leituras sujas” e formalmente não permite definir o nível de leitura repetitiva, ou seja, suporta apenas (por padrão) Read committede Serializable. Ao mesmo tempo, no nível de comandos individuais, ele realmente garante a repetibilidade de leitura (se um comando SELECTna primeira transação selecionar um conjunto de linhas do banco de dados e, nesse momento, uma segunda transação paralela alterar algumas dessas linhas, o o conjunto de resultados recebido pela primeira transação conterá linhas inalteradas, como se não houvesse uma segunda transação). O Oracle também oferece suporte às chamadas READ-ONLYtransações, que correspondem a Serializable, mas não podem alterar os próprios dados.

E o Microsoft SQL Server suporta todos os quatro níveis padrão de isolamento da transação e, adicionalmente, o nível SNAPSHOT, no qual a transação vê o estado dos dados que foram confirmados antes de ser lançada, bem como as alterações feitas por ela mesma, ou seja, ela se comporta como se recebeu na inicialização, um instantâneo dos dados do banco de dados e trabalha com ele. A diferença de Serialized é que nenhum bloqueio é usado, mas, como resultado, a confirmação de alterações pode não ser possível se uma transação simultânea tiver alterado os mesmos dados antes; neste caso, a segunda transação, ao tentar executar, COMMITgerará uma mensagem de erro e será cancelada.