Qual é a diferença entre leitura não repetível e leitura fantasma?
Eu li o artigo Isolamento (sistemas de banco de dados) da Wikipedia , mas tenho algumas dúvidas. No exemplo abaixo, o que acontecerá: a leitura não repetível e a leitura fantasma ?
Transação ASELECT ID, USERNAME, accountno, amount FROM USERS WHERE ID=1
RESULTADO:
1----MIKE------29019892---------5000
Transação B
UPDATE USERS SET amount=amount+5000 where ID=1 AND accountno=29019892;
COMMIT;
Transação A
SELECT ID, USERNAME, accountno, amount FROM USERS WHERE ID=1
Outra dúvida é, no exemplo acima, qual nível de isolamento deve ser usado? E porque?
database
oracle
transactions
isolation-level
transaction-isolation
user1357722
fonte
fonte
Respostas:
Da Wikipedia (que tem exemplos ótimos e detalhados para isso):
e
Exemplos simples:
select sum(x) from table;
retornará um resultado diferente, mesmo que nenhuma das linhas afetadas tenha sido atualizada, se as linhas foram adicionadas ou excluídas.Qual o nível de isolamento necessário depende do seu aplicativo. Há um alto custo para um nível de isolamento "melhor" (como concorrência reduzida).
No seu exemplo, você não terá uma leitura fantasma, porque seleciona apenas uma única linha (identificada pela chave primária). Você pode ter leituras não repetíveis. Se isso for um problema, convém ter um nível de isolamento que impeça isso. No Oracle, a transação A também pode emitir um SELECT FOR UPDATE; a transação B não pode alterar a linha até que A seja concluído.
fonte
Uma maneira simples de pensar sobre isso é:
As leituras não repetíveis e fantasmas têm a ver com operações de modificação de dados de uma transação diferente, que foram confirmadas após o início da transação e, em seguida, lidas pela transação.
Leituras não repetíveis são quando sua transação lê UPDATES confirmadas de outra transação. A mesma linha agora tem valores diferentes dos que tinham quando sua transação começou.
As leituras fantasmas são semelhantes, mas ao ler INSERTS e / ou DELETES confirmados de outra transação. Existem novas linhas ou linhas que desapareceram desde que você iniciou a transação.
As leituras sujas são semelhantes às leituras não repetíveis e fantasmas, mas estão relacionadas à leitura de dados NÃO COMPROMETIDOS, e ocorrem quando um UPDATE, INSERT ou DELETE de outra transação é lido e a outra transação ainda não confirmou os dados. Ele está lendo dados "em andamento", que podem não estar completos e nunca serem realmente confirmados.
fonte
Conforme explicado neste artigo , a anomalia de leitura não repetível tem a seguinte aparência:
Em este artigo sobre leitura fantasma , você pode ver que esta anomalia pode acontecer o seguinte:
Portanto, enquanto a leitura não repetível se aplica a uma única linha, a leitura fantasma é sobre um intervalo de registros que atendem a um determinado critério de filtragem de consulta.
fonte
Ler fenômenos
UPDATE
consulta de outra transaçãoINSERT
ouDELETE
consulta de outra transaçãoNota : As instruções DELETE de outra transação também têm uma probabilidade muito baixa de causar leituras não repetíveis em certos casos. Isso acontece quando a instrução DELETE, infelizmente, remove a mesma linha que sua transação atual estava consultando. Mas esse é um caso raro e muito mais improvável de ocorrer em um banco de dados com milhões de linhas em cada tabela. As tabelas que contêm dados de transação geralmente têm alto volume de dados em qualquer ambiente de produção.
Também podemos observar que ATUALIZAÇÕES pode ser um trabalho mais frequente na maioria dos casos de uso do que INSERT ou DELETES reais (nesses casos, o risco de leituras não repetíveis permanece apenas - leituras fantasmas não são possíveis nesses casos). É por isso que as atualizações são tratadas de forma diferente de INSERT-DELETE e a anomalia resultante também é nomeada de maneira diferente.
Também há um custo de processamento adicional associado ao manuseio de INSERT-DELETEs, em vez de apenas manipular as ATUALIZAÇÕES.
Benefícios de diferentes níveis de isolamento
Por que não definir a transação SERIALIZABLE o tempo todo? Bem, a resposta para a pergunta acima é: A configuração SERIALIZABLE torna as transações muito lentas , o que novamente não queremos.
De fato, o consumo de tempo de transação está na seguinte taxa:
Portanto, a configuração READ_UNCOMMITTED é a mais rápida .
Resumo
Na verdade, precisamos analisar o caso de uso e decidir um nível de isolamento para otimizar o tempo da transação e também evitar a maioria das anomalias.
Observe que os bancos de dados, por padrão, têm a configuração REPEATABLE_READ.
fonte
Há uma diferença na implementação entre esses dois tipos de níveis de isolamento.
Para "leitura não repetível", é necessário o bloqueio de linhas.
Para "leitura fantasma", é necessário o bloqueio de escopo, mesmo um bloqueio de tabela.
Podemos implementar esses dois níveis usando o protocolo de bloqueio de duas fases .
fonte
Em um sistema com leituras não repetíveis, o resultado da segunda consulta da Transação A refletirá a atualização na Transação B - verá o novo valor.
Em um sistema que permite leituras fantasmas, se a Transação B inserir uma nova linha com ID = 1, a Transação A verá a nova linha quando a segunda consulta for executada; isto é, leituras fantasmas são um caso especial de leitura não repetível.
fonte
A resposta aceita indica acima de tudo que a chamada distinção entre os dois não é realmente significativa.
Se "uma linha é recuperada duas vezes e os valores dentro da linha diferem entre as leituras", eles não são a mesma linha (não é a mesma tupla na fala correta do RDB) e é, por definição, também o caso em que "a coleção de linhas retornadas pela segunda consulta são diferentes da primeira ".
Quanto à pergunta "qual nível de isolamento deve ser usado", quanto mais seus dados forem de vital importância para alguém, em algum lugar, mais será o caso de Serializable ser sua única opção razoável.
fonte
Eu acho que há alguma diferença entre leitura não repetível e leitura fantasma.
O Não repetitivo significa que há uma transação de reboque A e B. se B pode notar a modificação de A, então talvez aconteça uma leitura suja, então deixamos B notar a modificação de A após A confirmar.
Há uma nova questão: deixamos B notar a modificação de A após A confirmar, significa A modificar um valor da linha que o B está mantendo; em algum momento B lerá a linha novamente, para que B tenha um novo valor diferente na primeira vez que get, chamamos de Não repetível, para lidar com o problema, deixamos o B lembrar de algo (porque eu ainda não sei o que será lembrado) quando B começar.
Vamos pensar na nova solução, também podemos notar que há um novo problema, porque deixamos B lembrar algo, então o que aconteceu em A, o B não pode ser afetado, mas se B quiser inserir alguns dados na tabela e B verifique a tabela para garantir que não haja registro, mas esses dados foram inseridos por A; talvez ocorra algum erro. Nós chamamos de leitura fantasma.
fonte
leitura não repetível é um nível de isolamento e leitura fantasma (leitura do valor confirmado por outras transações) é um conceito (tipo de leitura, por exemplo, leitura suja ou leitura de instantâneo). O nível de isolamento de leitura não repetível permite leitura fantasma, mas não leituras sujas ou instantâneas.
fonte