Oracle
 sql >> Datenbank >  >> RDS >> Oracle

Orakel - Sequenzen ohne Sequenz

Obwohl ich dringend davon abraten würde (es vorziehen, eine einzelne Sequenz zu verwenden und einfach zu akzeptieren, dass es größere als erwartete Lücken geben wird), können Sie Ihre eigene Pseudo-Sequenz-Tabelle erstellen

CREATE TABLE my_sequences (
  sequence_name VARCHAR2(30) PRIMARY KEY,
  sequence_val  NUMBER
);

Ein paar Zeilen einfügen

INSERT INTO my_sequences( sequence_name, sequence_val )
  VALUES( 'GroupA', 1 );
INSERT INTO my_sequences( sequence_name, sequence_val )
  VALUES( 'GroupB', 1 );

und schreiben Sie dann eine Funktion, um den nächsten Sequenzwert zu erhalten

CREATE FUNCTION get_nextval( p_sequence_name IN VARCHAR2 )
  RETURN NUMBER
IS
  l_val NUMBER;
BEGIN
  SELECT sequence_val
    INTO l_val
    FROM my_sequences
   WHERE sequence_name = p_sequence_name
     FOR UPDATE;

  UPDATE my_sequences
     SET sequence_val = sequence_val + 1
   WHERE sequence_name = p_sequence_name;

  RETURN l_val;
END;

Dadurch wird die Zeile in der Tabelle für die bestimmte Sequenz gesperrt, bis die Transaktion, die die nächste Zeile abgerufen hat, entweder festgeschrieben oder zurückgesetzt wird. Dadurch wird die Skalierbarkeit Ihrer Anwendung im Vergleich zur Verwendung von Oracle-Sequenzen radikal verringert, indem sichergestellt wird, dass nur eine Sitzung eine Zeile für einen bestimmten group_name einfügen kann gleichzeitig - die anderen blockieren das Warten auf die Sequenz. Wenn Sie ein System mit einer relativ kleinen Anzahl gleichzeitiger Benutzer (oder einer relativ großen Anzahl von group_name Werte), die für Sie akzeptabel sein können. Aber im Allgemeinen ist es eine schlechte Praxis. Abhängig von der Oracle-Version können Sie möglicherweise autonome Transaktionen verwenden, um die Parallelität zu erhöhen, aber das fügt der Lösung nur ein weiteres bisschen Komplexität hinzu. An dem Punkt, an dem Sie sich wirklich Sorgen um die Skalierbarkeit machen, möchten Sie wirklich das gesamte Design zurückdrängen und einfach eine Oracle-Sequenz verwenden.