Ich versuche, eine Sequenz in einer Oracle-Datenbank zu implementieren, die als Ersatzschlüsselersteller für eine Tabelle fungiert. Aus Leistungsgründen möchte ich, dass diese Sequenz zwischengespeichert wird. Ich habe gelesen, dass es potentielle Fallstricke gibt, wenn zwischengespeicherte Sequenzen verwendet werden, da Rollbacks und Instanzenfehler zu fehlenden Werten führen.
Das hat mich zum Nachdenken gebracht. Nehmen wir an, ich erstelle eine Sequenz mit einer Cachegröße von 100. Dann mache ich eine Einfügung für 50 Datensätze in meine Tabelle, wobei der Sequenzwert der primäre Ersatzschlüssel ist. Nach dem Festschreiben wäre der aktuelle Wert der Sequenz noch nicht auf die Platte geschrieben worden. Angenommen, ich hätte zu diesem Zeitpunkt einen Fehler in der Instanz. Wenn die Datenbank wieder verfügbar ist, wird der aktuelle Sequenzwert auf den letzten auf die Festplatte geschriebenen Wert zurückgesetzt.
Wenn ich versuchen würde, weitere 50 Datensätze in meine Tabelle einzufügen, werde ich jetzt die Primärschlüsselbeschränkung aufheben, weil die Sequenz von der Platte auf ihren letzten Zustand zurückgesetzt wurde und die Primärschlüssel jetzt wiederverwendet werden? Wenn dies der Fall ist, wie würde ich das verhindern?
Nein, das wird nicht der Fall sein.
Ihre Sequenz wird bei 101
fortgesetzt, die Werte zwischen 50
und 100
fehlen.
Der einzige Grund, das Sequenz-Caching zu deaktivieren, ist der Versuch, Lücken in der Sequenz zu vermeiden, die für die meisten Primärschlüssel nicht relevant sind.
Sie könnten an diesem Artikel interessiert sein, was besagt, dass
Der Nachteil beim Erstellen einer Sequenz mit einem Cache ist das, wenn ein System Fehler tritt auf, alle zwischengespeicherte Sequenz Werte, die nicht verwendet wurden, werden "hat verloren". Dies führt zu einer "Lücke" in der zugewiesene Sequenzwerte. Wenn das System kommt zurück, Oracle wird Cache neue Zahlen von wo es ging in der Folge aus, ignorieren die so "verlorene" Sequenzwerte genannt.
Sagen Sie, der Cache hat die Werte 101-200. Der Wert auf der Festplatte ist 201. Ihr Insert verwendet 101-150. Die Instanz geht unter. Die Instanz wird gestartet. Das nächste Mal, wenn die Sequenz verwendet wird, wird 201-300 zwischengespeichert.
Stellt sich heraus, dass dies nicht (oder nicht mehr wahr) ist. Beim Herunterfahren und Neustarten der Instanz werden die zwischengespeicherten Werte nicht verloren. Einfacher Test mit Cache = 1000.
SQL & gt; Wählen Sie ordered.currval aus dual;
SQL & gt; Wählen Sie unordered.currval aus dual
ausSQL & gt; ABSCHALTEN SOFORT SQL & gt; STARTUP
SQL & gt; Wählen Sie unordered.nextval aus dual;
Außerdem speichert ALL_SEQUENCES.LAST_NUMBER nicht die letzte von der Sequenz bereitgestellte Nummer, außer beim Start und vor dem ersten NEXTVAL. Nach dem ersten NEXTVAL, hält es die letzte Nummer serviert plus CACHE_SIZE. Dies ändert sich erst, wenn ein neuer Cache generiert wird. Beim Herunterfahren wird es jedoch anscheinend nur auf die zuletzt versorgte Nummer zurückgesetzt.