Pourquoi les transactions non validées doivent-elles être annulées dans l'ordre inverse?

19

J'ai un journal de base de données où certaines transactions gagnent (elles sont validées avant le crash) et certaines perdent (pas encore validées). Nous avons appris en classe que les actions des perdants doivent être annulées à l'envers.

Y a-t-il une raison pour faire cela à l'envers? Quelqu'un peut-il donner un exemple simple d'un journal où les annulations avant donneraient de mauvais résultats?

prjctdth
la source
Cette question ne devrait-elle pas être posée dans un autre site Web plus spécifique?
nbro

Réponses:

35

Transactions originales:

  1. Insérez l'enregistrement .r
  2. Mettez à jour un champ de r .Fr

Annuler vers l'avant:

  1. Supprimer l'enregistrement .r
  2. Inversez la mise à jour en - oh attendez, r n'existe plus! Cela provoque une erreur.rr
DylanSp
la source
Les choses doivent-elles être physiquement annulées individuellement dans l'ordre inverse si le système peut déterminer dans quel état les choses doivent être restaurées et peut appliquer toutes les modifications nécessaires avant de traiter quoi que ce soit d'autre?
supercat
11
L'annulation des modifications dans l'ordre inverse facilite la tâche. Pourquoi voudriez-vous vous compliquer la vie?
gnasher729
1
Non, le système ne fera pas tout, mais le fera toujours dans l'ordre inverse.
Evil
3
Dans de nombreux systèmes de bases de données du monde réel, il ne serait même pas possible de le faire dans l'ordre inverse en raison de contraintes clés sur les tables.
SeanR
11

Pour ajouter à la réponse de DylanSp, essayer de mettre à jour un champ dans un enregistrement inexistant échouera, mais le résultat sera toujours le résultat attendu: l'enregistrement r n'existe pas.

Cependant, considérez une situation où la suppression d'un enregistrement échouera réellement:

  1. Insérez la commande O.
  2. Insérer la ligne de commande L.

Supposons, de façon non irréaliste, que chaque ligne de commande doit être liée à une commande.

Désormais, l'annulation de la transaction en commençant par la suppression de la commande échouera, car cela violerait notre règle commerciale.

Donc après

  1. Supprimer la commande O. (ÉCHEC)
  2. Supprimer Ordeline L. (SUCCÈS)

Nous pouvons nous retrouver avec une commande existante (sans ligne de commande).

Bien sûr, dans ce cas, nous pourrions utiliser une suppression en cascade, mais cela signifierait que l'étape 2 échouerait (sans impact). Pire encore, il peut être indésirable de mettre en œuvre des suppressions en cascade sur les commandes.

oerkelens
la source
D'accord, cela a du sens. Thx pour votre aide
prjctdth
Est-il approprié de supposer que les contraintes n'ont pas été violées avant ou après la transaction dans des circonstances "normales"? Par normal, je veux dire que la transaction n'aurait pas échoué si une seule personne utilisait la base de données. Si cela est vrai, pourquoi serait-il important de ne pas introduire de violations de contraintes pendant le processus d'annulation? Il semble que les contraintes pourraient être désactivées au début de l'annulation et activées une fois l'opération terminée.
Noctis Skytower
2
@NoctisSkytower La désactivation des contraintes lors d'une opération d'E / S normale les rend inutiles. Ils existent pour une raison. Mon exemple illustre clairement comment les contraintes peuvent être respectées dans des circonstances normales, mais violées lors de la restauration. La désactivation des contraintes lors de la restauration complique inutilement les problèmes et résout le problème incorrect. Le problème n'est pas la contrainte, le problème est sa violation en essayant incorrectement de revenir en arrière.
oerkelens
Oui, cela a du sens, mais pourquoi vérifier les contraintes lors de la restauration? En supposant que les restaurations sont conçues pour être garanties sans problème, pourquoi perdre inutilement du temps à vérifier les contraintes s'il est connu qu'elles ne seront pas violées au moment où la restauration se terminera? BTW, cela devrait être une garantie car si un retour en arrière échouait, la DB aurait apparemment besoin d'un retour en arrière, ce qu'elle ne peut pas faire.
Noctis Skytower
1
@NoctisSkytower, il devrait être impossible pour la base de données d'être dans un état où les contraintes sont violées, même s'il s'agit d'un état temporaire. Si tout le rollback est atomique, peu importe l'ordre dans lequel il se produit car il n'y a pas d'ordre, c'est une seule instruction qui "se produit tout à la fois". s'il y a deux transactions ou plus qui sont annulées séparément dans un certain ordre, alors il est obligatoire que l'ordre soit tel que tout observateur lisant les données au milieu ne puisse voir qu'une situation où toutes les contraintes tiennent.
Peteris
6

Allons par analogie: disons que tu sors dîner.

  1. Mettez des chaussettes.
  2. Mettez des chaussures.
  3. Se lever.
  4. Marchez jusqu'à la porte.

Ensuite, vous recevez un appel téléphonique. Les plans du dîner ont été annulés.

  1. Enlevez vos chaussettes.
  2. Enlevez vos chaussures.
  3. Asseyez-vous.
  4. Éloignez-vous de la porte.

Quelque chose ne va pas là-dedans. Vous pourriez trébucher et vous blesser. Ou plus probablement, vous vous rendrez compte que certaines actions ne peuvent pas être annulées avant que les actions ultérieures ne soient annulées en premier.

Annuler la dernière chose que vous faisiez vous ramène à l'endroit où vous étiez lorsque l'avant-dernière étape s'est produite. Ensuite, vous annulez cette étape et répétez, en reculant jusqu'à ce qu'il ne reste plus rien. D'un autre côté, inverser la première étape peut ne pas être possible étant donné les états qui suivent les étapes ultérieures.

mathématiquement parlant: les actions peuvent ne pas commuer, donc chaque fois que cela importe quelle étape vous effectuez en premier ou en second, l'ordre dans lequel vous annulez les étapes importera.

Joel
la source
3

C'est juste parce que les transactions sont construites les unes sur les autres et le résultat d'une transaction dépend beaucoup de la situation avant sa validation.

Regardons les transactions financières:

(au début, avant que les transactions ne ame doivent 100 USD)

  1. a me doit 100 USD (maintenant la dette totale 200)
  2. areçoit 10% de réduction sur ce qu'il me doit. (maintenant dette totale 180)

Disons que je veux annuler les deux transactions.

Si nous annulons le premier en premier, nous nous retrouverons avec:

  1. moins de dettes 100 (maintenant 80 dettes)
  2. annuler 10% de réduction (avoir maintenant une dette 80 / 0,9 = 88)

C'est faux, nous devons retrouver une dette de 100. Ce sera correct si nous annulons les transactions dans l'ordre inverse.

  1. annuler la remise - maintenant la dette est de 200
  2. une dette inférieure à 100 - maintenant la dette est de 100
thebeancounter
la source
2

Supposons qu'il existe une table T avec une seule colonne.

Supposons que le «journal d'annulation» est un fichier de base de données contenant des transactions non validées et que le «journal de restauration» est un fichier de base de données contenant à la fois des transactions non validées et validées qui n'ont pas encore été appliquées aux fichiers de données.

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:

              The committed values in T are still 101, 102 and 103.

              Since 201, 202, and 203, and 251, 252 and 253
              are not committed, if they are written into the "redo
              log" of the database, there is a need to "roll back"
              the transactions AFTER the "redo log" is applied.

              Since 201, 202, and 203, and 251, 252 and 253
              are not committed, they are in the "undo log"
              of the database.

              The undo log of the database is used BOTH to (1) roll
              back a transaction that is deliberately rolled 
              back in the memory structure of the database instance, 
              and also (2) during the instance recovery at 8:40 A.M.

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.

              The undo log has not yet been applied.

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.

Pourquoi les DEUX transactions validées et non validées sont-elles écrites dans le fichier journal de rétablissement? La raison en est de fournir une récupération ponctuelle.

Cela signifie que le contenu du fichier "refaire le journal" n'est PAS cohérent avec les transactions. Pour cette raison, chaque fois que le journal de rétablissement est utilisé pour appliquer des transactions validées aux fichiers de données, le "journal d'annulation" DOIT ÉGALEMENT être utilisé pour annuler des transactions non validées.

Pourquoi les transactions du "journal d'annulation" sont-elles annulées dans l'ordre inverse? La transaction 300 a ajouté 50 à la valeur existante de chaque colonne de chaque ligne. Par conséquent, si la transaction 200 est annulée en premier, les valeurs passeront de 251, 252 et 253 à 201, 202 et 203. Si la transaction 300 était ensuite annulée en dernier, les valeurs seraient 151, 152 et 153 - qui ne correspondent pas les valeurs initiales engagées.

LES RÉFÉRENCES:

https://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:1670195800346464273

UN B
la source
0

Ce n'est pas intrinsèquement vrai. La restauration peut simplement réappliquer les blocs qui ont été mis en cache dans le journal d'annulation afin que l'état final soit le même que l'état initial. Étant donné que le journal a été écrit dans l'ordre avant, j'ai fait que ma restauration s'applique également dans l'ordre avant. L'ordre n'avait aucune importance, car la restauration allait réessayer jusqu'à ce que le fichier journal soit marqué comme réglé.

Joshua
la source