Was sind die Ursachen und Lösungen für mutierende Tabellenfehler?

12

Ich verstehe, dass mutierende Tabellenfehler durch einen Designfehler oder eine problematische Abfrage verursacht werden.

Kürzlich wurde eine alte Abfrage in Betrieb genommen, die einen Fehler in der mutierenden Tabelle auslöst. Unser DBA hat das Problem gelöst, aber wir wissen nicht wie.

Was genau verursacht mutierende Tabellenfehler und wie hätte unser DBA das Problem behoben?

Parmanand
quelle

Antworten:

17

Die wahrscheinlichste Ursache für einen mutierenden Tabellenfehler ist der Missbrauch von Triggern. Hier ist ein typisches Beispiel:

  1. Sie fügen eine Zeile in Tabelle A ein
  2. Ein Trigger für Tabelle A (für jede Zeile) führt eine Abfrage für Tabelle A aus, um beispielsweise eine Zusammenfassungsspalte zu berechnen
  3. Oracle löst einen ORA-04091 aus: Tabelle A mutiert, Trigger / Funktion sehen ihn möglicherweise nicht

Dies ist ein erwartetes und normales Verhalten. Oracle möchte Sie vor sich selbst schützen, da Oracle Folgendes garantiert:

  • (i) dass jede Anweisung atomar ist (dh entweder fehlschlägt oder vollständig erfolgreich ist)
  • (ii) dass jede Aussage eine konsistente Sicht auf die Daten sieht

Wenn Sie diese Art von Trigger schreiben, erwarten Sie höchstwahrscheinlich, dass die Abfrage (2) die Zeile sieht, die in (1) eingefügt wurde. Dies steht im Widerspruch zu beiden obigen Punkten, da die Aktualisierung noch nicht abgeschlossen ist (es könnten weitere Zeilen eingefügt werden).

Oracle konnte das Ergebnis in Übereinstimmung mit einem Zeitpunkt unmittelbar vor dem Beginn der Anweisung zurückgeben, aber aus den meisten Beispielen, die ich gesehen habe, um diese Logik zu implementieren, sehen die Leute eine mehrzeilige Anweisung als eine Reihe aufeinanderfolgender Schritte und erwarten die Anweisung [2], um die durch die vorherigen Schritte vorgenommenen Änderungen anzuzeigen. Oracle kann das erwartete Ergebnis nicht zurückgeben und löst daher den Fehler aus.

Zum weiterlesen: "mutating table" auf Ask Tom .

Wenn, wie ich vermute, die Ursache des Fehlers in der mutierenden Tabelle ein Trigger ist, besteht eine Möglichkeit, den Fehler zu vermeiden, darin, die Logik aus dem Trigger in Prozeduren zu verschieben.

Vincent Malgrat
quelle
9

Eine Mutieren Tabelle tritt auf, wenn eine Anweisung , um einen Trigger ausgelöst verursacht und dass Trigger verweist auf die Tabelle, die den Trigger verursacht. Der beste Weg, solche Probleme zu vermeiden, besteht darin, keine Trigger zu verwenden, aber ich vermute, der DBA hat sich nicht die Zeit genommen, dies zu tun. Er hätte eine der folgenden Aktionen ausführen können:

Leigh Riffel
quelle
1
Zumindest für mich schlägt der Wechsel zu einem After-Trigger am 11.2.0.4.0
Outfast Source
Auch für mich; Version 12.1.0.2.0 und AFTER funktioniert nicht.
eidylon