Frage

Die Möglichkeit, dass dies geschieht, scheint äußerst unwahrscheinlich, mich wegen der Probleme könnte es dazu führen, aber ich dachte, ich die Frage stellen würde sowieso ...

Stellen Sie sich eine Transaktion, bei der eine Autoinkrement ID beteiligt ist und ein Wert zugewiesen wird. Vor COMMIT speichert der beteiligten Code eine Kopie der zugewiesene ID für den späteren Gebrauch auf. Dann wird die Transaktion festgeschrieben.

Unter der Annahme, keine direkte Client-Intervention (Streichung oder Verfälschung des Datensatz), gibt es eine Datenbank oder eine Situation, die jemals automatisch den ID-Wert unmittelbar nach COMMIT ändern würde, die im Cache gespeicherte ID falsch machen? Ist es immer sicher, die ID Mitte Transaktion zwischenzuspeichern?

Eine hypothetische Fall, wo ich das passiert vorstellen kann, ist, wenn einige RDBMS Implementierung aus unerklärlichen Gründen entschieden, war es notwendig, gapless und zeitabhängige autoincrement Werte zu haben (da ich viele Beispiele von Menschen wollen diese sehen). In diesem hypothetischen Fall kann ich einige magischen Schlurfen von IDs vorstellen können in Lücken, die durch Post-ID-Zuordnung Rollbacks in einer anderen Transaktion (oder anderer Lücke causer) zu füllen erfolgen. Dies würde den zwischengespeicherten Wert ungültig machen.

Wer weiß, von einer solchen Implementierung oder andere Cache-Killer?

War es hilfreich?

Lösung

Die Umsetzung der erzeugten ID-Werte in der Regel einen Zählerwert in einer kurzen atomaren Operation erhöht wird. Dieser Wert wird dann von der ersuchenden Transaktion verwendet und auch wenn diese Transaktion zurück rollen würde, der reservierte Wert wird nie wieder in den Pool des freien Wertes gegeben werden. Also in diesem Licht nicht, daß ich denke, die Situation beschrieben sehr wahrscheinlich ist. Auch in PL / SQL Art von Programmen, die Sie wirklich den generierten Wert brauchen Recht zu sein, um andere abhängige Zeilen einfügen zu untergeordneten Tabellen.

Wie für die Menschen, die zeitlich geordnete Gapless-ID-Werte werden zu wollen: Der einzige Zweck der Autoinkrement / Ersatzschlüssels ist eine künstliche Identifizierung für eine Zeile zu erstellen. Es sollte nichts mit Festlegung der Reihenfolge zu tun, in der Zeilen erstellt wurden. Es gibt viel bessere Möglichkeiten, dies zu tun, zum Beispiel eine Schöpfung Zeitstempel verwendet wird.

Andere Tipps

PostgreSQL unterstützt DEFERRED Auslöser, die die Daten über COMMIT verändern können.

CREATE TABLE test_autoinc (id BIGSERIAL);

CREATE TABLE test_other (id BIGSERIAL);

CREATE FUNCTION prc_update_autoinc()
RETURNS TRIGGER
AS
$$
BEGIN
        UPDATE  test_autoinc
        SET     id = id + 10;
        RETURN  NEW;
END;
$$
LANGUAGE 'plpgsql';

CREATE CONSTRAINT TRIGGER
        trg_other_ai
AFTER INSERT
ON      test_other
DEFERRABLE
INITIALLY DEFERRED
FOR EACH ROW
EXECUTE PROCEDURE prc_update_autoinc();

BEGIN TRANSACTION;

INSERT
INTO    test_autoinc
DEFAULT VALUES;

INSERT
INTO    test_other
DEFAULT VALUES;

SELECT  *
FROM    test_autoinc;

COMMIT;

SELECT  *
FROM    test_autoinc;

Der erste SELECT (direkt vor dem COMMIT) kehrt 1, die zweite (direkt nach dem COMMIT) gibt 11.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top