Zurück

How to implement a Primary Key Generator ?

Übersicht

Um Primary Keys zu generieren bietet Oracle grundsätzlich Sequences an. Sequences erfüllen die Anforderungen zum generieren von Surrogate (künstlichen) Keys wie beispielsweise: Kein Locking wenn mehrere Sessions gleichzeitig einen Key verlangen. Sequences können "Löcher" aufweisen, was in der Regel keine Rolle spielt für Primary Keys. Der wesentlichste Nachteil von Sequences besteht darin, dass sie keine applikationsabhängigen Keys generieren. Der folgende Artikel, zeigt wie ein Primary Key Generator implementiert werden kann, mit allen "Sequence-Features" und zusätzlich der Möglichkeit applikationsabhängige Keys zu generieren.

Schritte um multiuserfähigen, lockingfreien Key zu generieren.

  • Key Tabelle erstellen: Der applikationsspezifische Key wird in einer Tabelle abgelegt
  • Key aus der Tabelle lesen
  • Key um 1 oder applikationsspezifischen Wert erhöhen.
  • Key zurückschreiben
  • Key erneut lesen

Das Wichtigste bei diesem Ablauf ist, dass der Key nach dem Lesen SOFORT wieder zurückgeschrieben und erneut gelesen wird aus der gleichen Transaktion. Nach dem COMMIT wird der Lock, welcher durch das FOR UPDATE erstellt wurde wieder aufgehoben. Die Ausführungszeit ist derart kurz, dass die Tabelle KEYTAB nur für einen sehr kleinen Zeitschlitz gelockt ist.

1).  Key Tabelle erstellen und initialisieren

CREATE TABLE keytab (key NUMBER(20) NOT NULL);
INSERT INTO keytab VALUES (0);
COMMIT;

2). Funktion get_key() erstellen

Die Applikation benutzt ausschliesslich diese Funktion um den Key zu generieren.

CREATE OR REPLACE
Function GetKey RETURN  NUMBER IS
  numKey   keytab.key%TYPE;
BEGIN
  --
  -- Get current key from Table KEYTAB
  --

  SELECT key INTO numKey
    FROM keytab
     FOR UPDATE OF key;
  --
  -- Very quick update KEYTAB Table ...
  --

  UPDATE keytab SET key = (numKey + 1);
  --
  -- ... and get the new Key back from the Table
  --

  SELECT key INTO numKey
    FROM keytab
  --
  -- Release all Locks
  --

  COMMIT;
  --
  RETURN numKey;
END;
/

3). Benutzen der GetKey Funktion

Procedure TestKey IS
  newKey   keytab.key%TYPE;
Begin
  newKey := getKey;
  dbms_output.put_line('NewKey:' || TO_CHAR(newKey));
END;

SQL> execute testkey;
NewKey:1

PL/SQL procedure successfully completed.