Eu tenho um log de banco de dados em que algumas transações vencem (elas são confirmadas antes da falha) e outras perdem (ainda não confirmadas). Aprendemos em sala de aula que as ações dos perdedores devem ser desfeitas para trás.
Existe alguma razão para fazer isso ao contrário? Alguém pode dar um exemplo simples de um log em que desfazer encaminhamentos daria resultados incorretos?
concurrency
databases
prjctdth
fonte
fonte
Respostas:
Transações originais:
Desfazer frente:
fonte
Para adicionar à resposta do DylanSp, a tentativa de atualizar um campo em um registro não existente falhará, mas o resultado ainda será o esperado: o registro r não existe.
No entanto, considere uma situação em que a exclusão de um registro realmente falhará:
Vamos supor, de maneira não irrealista, que todo OrderLine deve estar relacionado a um Pedido.
Agora, a reversão da transação começando com a exclusão do Pedido falhará, pois isso violaria nossa regra de negócios.
Então depois
Podemos terminar com um pedido existente (sem uma linha de pedido).
Obviamente, nesse caso, poderíamos usar uma exclusão em cascata, mas isso significaria que a etapa 2 falharia (sem impacto). Pior, pode ser um comportamento indesejável implementar exclusões em cascata nos pedidos.
fonte
Vamos por analogia: diga que você está saindo para jantar.
Então você recebe uma ligação. Planos de jantar cancelados.
Algo dá errado lá. Você pode tropeçar e se machucar. Ou, mais provavelmente, você perceberá que algumas ações não podem ser desfeitas até que ações posteriores sejam desfeitas primeiro.
Desfazer a última coisa que você estava fazendo leva você de volta para onde estava quando ocorreu a penúltima etapa. Em seguida, você desfaz essa etapa e repete, voltando até que nada reste. Por outro lado, a reversão da primeira etapa pode não ser possível, considerando os estados que seguem as etapas posteriores.
matematicamente falando: as ações podem não ser comutadas; portanto, sempre que importa qual etapa você executa primeiro ou segundo, a ordem na qual você desfaz as etapas será importante.
fonte
Isso é certo porque as transações são construídas umas sobre as outras e o resultado de uma transação depende muito da situação antes de ser confirmada.
Vejamos as transações financeiras:
(no início, antes das transações
a
me deverem 100 USD)a
me deve 100 USD (agora dívida total 200)a
recebe 10% de desconto sobre o que ele me deve. (agora dívida total 180)Digamos que eu queira cancelar as duas transações.
Se cancelarmos o primeiro primeiro, terminaremos com:
Isso está errado, precisamos voltar à dívida de 100. Isso será correto se cancelarmos as transações na ordem inversa.
fonte
Suponha que exista uma tabela T com apenas uma coluna.
Suponha que o "desfazer log" é um arquivo de banco de dados que contém transações não confirmadas e que o "refazer log" é um arquivo de banco de dados que contém transações confirmadas e não confirmadas que ainda não foram aplicadas aos arquivos de dados.
At 8:00 A.M., Transaction 100 inserts rows with values 101, 102 and 103 into table T. At 8:10 A.M., Transaction 100 is committed and the commit for transaction 100 completes. At 8:15 A.M., Transaction 200 updates row 101 to 201, 102 to 202 and 103 to 203. At 8:20 A.M., Transaction 200 has not been committed and remains in the undo log of the database. At 8:25 A.M., Transaction 300 increments each row by 50, changing row 201 to 251, 202 to 252, and 203 to 253. At 8:30 A.M., Transaction 300 has not been committed and remains in the undo log of the database. At 8:35 A.M., The instance providing access to the database crashes.
At 8:40 A.M., The instance is restarted, and the database files are opened as the instance is started:
At 8:41 A.M., The redo log has been applied, and the T table contains values 251, 252 and 253 in the instance memory.
At 8:42 A.M., The undo log is applied in the reverse order: Uncommitted transaction 300 is undone, and Uncommitted transaction 200 is undone.
Por que ambas as transações confirmadas e não confirmadas são gravadas no arquivo de log refazer? A razão para isso é fornecer recuperação point-in-time.
Isso significa que o conteúdo do arquivo "refazer log" NÃO é consistente com as transações. Por esse motivo, sempre que o redo log for usado para aplicar transações confirmadas aos arquivos de dados, o "desfazer log" DEVE TAMBÉM ser usado para reverter transações não confirmadas.
Por que as transações no "desfazer log" são revertidas na ordem inversa? A transação 300 adicionou 50 ao valor existente de cada coluna de cada linha. Portanto, se a transação 200 for revertida primeiro, os valores serão alterados de 251, 252 e 253 para 201, 202 e 203. Se a transação 300 fosse revertida por último, os valores seriam 151, 152 e 153 - que não correspondem os valores comprometidos originais.
REFERÊNCIAS:
https://asktom.oracle.com/pls/asktom/f?p=100:11.0:::: P11_QUESTION_ID:1670195800346464273
fonte
Não é inerentemente verdade. A reversão pode simplesmente reaplicar os blocos que foram armazenados em cache no log de desfazer, para que o estado final seja o mesmo que o estado inicial. Como o log foi gravado na ordem de encaminhamento, eu fiz minha reversão também ser aplicada na ordem de encaminhamento. O pedido não importava porque a reversão tentaria novamente até que o arquivo de log fosse marcado como resolvido.
fonte