MySQL Trigger, um einen Hash für einen Auto_Increment-Index zu generieren

8

Ich versuche einen Trigger zu erstellen, der einen Hash für den auto_increment-Index generiert und speichert, aber alle Lösungen, die ich ausprobiert habe, haben nicht funktioniert:

%Vor%

Es besagt, dass ich ein NEW nach dem INSERT nicht ändern kann, und vor dem INSERT habe ich nicht den auto_increment Wert:

FEHLER 1442 (HY000): Tabelle 'Tabelle1' in gespeicherter Funktion / Trigger kann nicht aktualisiert werden, da sie bereits von Anweisung verwendet wird, die diese gespeicherte Funktion / Trigger aufgerufen hat.

    
ppaulojr 07.06.2013, 13:16
quelle

1 Antwort

5

Sie können den Wert nicht mehr ändern nachdem die Zeile eingefügt wurde. Daher ist SET NEW.column nur in BEFORE trigger verfügbar.

Sie können auch kein reguläres UPDATE entweder weil verwenden :

  

Eine gespeicherte Funktion oder ein Trigger kann eine bereits vorhandene Tabelle nicht ändern   verwendet (zum Lesen oder Schreiben) von der Anweisung, die die aufgerufen hat   Funktion oder Auslöser.

Schließlich wurde in BEFORE INSERT der Wert AUTO_INCREMENT noch nicht generiert und NEW.id ist 0 .

Der Trick: Überprüfen Sie in einem BEFORE -Trigger manuell die Tabellendefinition für den nächsten AUTO_INCREMENT -Wert:

ACHTUNG: Dies funktioniert nur mit MyISAM, nicht mit InnoDB

I Angenommen, könnte mit InnoDB funktionieren, wenn innodb_autoinc_lock_mode = 0 , aber ich kann nicht sicher sagen.

%Vor%

[Bearbeiten 1]

Was die gleichzeitige Beweiseigenschaft dieses Ansatzes betrifft, kann ich sagen:

  • Mit MyISAM, wo nur Table-Locks verfügbar sind, ist die Sicherheit offensichtlich: Eine exklusive Sperre für die Tabelle (n) wird von einem beliebigen INSERT / UPDATE / DELETE übernommen und nicht gleichzeitig Zugriff kann passieren.

  • Mit InnoDB ist das weniger offensichtlich. Für den " traditionellen Sperrmodus " heißt es im Handbuch:

  

InnoDB verwendet eine spezielle Sperre, die AUTO-INC-Sperre auf Tabellenebene für   fügt in Tabellen mit AUTO_INCREMENT-Spalten ein. Diese Sperre ist normalerweise   bis zum Ende der Erklärung gehalten

Ich nehme an, das ist in diesem Fall sicher.

Ich bin nicht vertraut mit diesen Konzepten, also konnte ich nicht sicher sagen. Es scheint in der Tat zweifelhaft.

[Bearbeiten 2]

Ich habe den folgenden Test mit verschiedenen Einstellungen für innodb_autoinc_lock_mode :

CREATE TABLE t (     ai INT AUTO_INCREMENT PRIMÄRSCHLÜSSEL,     trigval INT,     Flagge BOOL );

Ein Trigger für die Tabelle führt SET NEW.trigval = next_ai mit der obigen Methode aus.

In einer Transaktion wird eine lange INSERT-Operation durchgeführt von:

%Vor%

In einer zweiten Transaktion gebe ich ständig die folgende Aussage aus:

%Vor%

Am Ende suche ich nach Diskrepanzen:

%Vor%

Mit innodb_autoinc_lock_mode = 0 ("traditionell") scheint es sicher zu sein. Jeder gleichzeitige Versuch, in die Tabelle einzufügen, wird bis zum Abschluss des langen INSERT gesperrt.

Allerdings habe ich nicht erwartet, dass dieser Ansatz mit den Modi 1 (Standard) und 2 einfach falsch ist . information_schema.tables.auto_increment wird in Schritten aktualisiert. Das ist das Ergebnis, das ich habe:

%Vor%     
RandomSeed 07.06.2013, 13:53
quelle

Tags und Links