Unterdrückt den doppelten Schlüsselwert gegen eindeutige Integritätsbedingungen

8

Ich entwickle eine Rails 3 App, die Postgres als Datenbank verwendet. Ich habe die folgende Tabelle:

%Vor%

Dies hat zwei Spalten:

  • id, das ist der Primärschlüssel (automatisch von rails erstellt)
  • some_other_id, die Schlüssel enthält, die von einem anderen System generiert wurden. Diese ID muss eindeutig sein, daher habe ich der Tabelle eine eindeutige Schlüsseleinschränkung hinzugefügt.

Wenn ich jetzt versuche, eine Zeile mit einem Duplikat some_other_id einzufügen, scheitert es (gut) und ich bekomme die folgende Ausgabe in meinen Postgres-Logs:

%Vor%

Das Problem ist, dass es völlig normal ist, dass meine App die selbe ID zweimal hinzufügt, und meine Logs werden mit dieser Fehlermeldung "ERROR" gespammt, was verschiedene Probleme verursacht: Dateien nehmen viel Festplattenplatz ein, Diagnose bekommt verloren im Lärm, muss Postgres diags wegwerfen, um die Protokolldateien innerhalb der Größengrenzen usw. zu behalten.

Weiß jemand wie ich das kann?

  • Unterdrücken Sie das Protokoll, indem Sie entweder alle Protokolle zu diesem Schlüssel unterdrücken oder indem Sie etwas in der Transaktion angeben, die versucht, INSERT .
  • auszuführen
  • Verwenden Sie eine andere Postgres-Funktion, um den doppelten Schlüssel zu erkennen, und versuchen Sie nicht INSERT . Ich habe von Regeln und Auslösern gehört, aber ich kann nicht arbeiten (obwohl ich kein Postgres-Experte bin).

Beachten Sie, dass jede Lösung mit Rails arbeiten muss, die ihre Einfügungen wie folgt ausführt:

%Vor%     
Alex Hockey 12.09.2012, 10:05
quelle

3 Antworten

10

Um den doppelten Schlüsselfehler zu vermeiden:

%Vor%

Ich gehe davon aus, dass id eine serielle Spalte ist, die ihren Wert automatisch erhält.

Dies unterliegt einer sehr kleinen Wettlaufsituation (im Zeitfenster zwischen SELECT und INSERT ). Aber das Schlimmste, was passieren kann, ist, dass Sie schließlich einen doppelten Schlüsselfehler bekommen und dies wird kaum jemals auftreten und sollte in Ihrem Fall kein Problem sein.

Sie können immer Raw-SQL verwenden, wenn Ihr Framework die Verwendung der richtigen Syntax einschränkt.

Oder Sie können eine UDF (benutzerdefinierte Funktion) für den Zweck erstellen:

%Vor%

Anruf:

%Vor%

Oder als Vorgabe für ein bereits vorhandenes id :

%Vor%

Auch hier bleibt eine minimale Chance für eine Race Condition. Sie können dies auf Kosten einer langsameren Leistung beseitigen:

Erwin Brandstetter 12.09.2012, 12:47
quelle
2

Sie können die Protokollierung von Fehlermeldungen für die Sitzung (oder global tatsächlich) deaktivieren, aber es erfordert Superuser-Privilegien:

Durch Ausführen:

%Vor%

Nur fatale Fehler werden protokolliert, bis die Sitzung (= Verbindung) beendet wird oder Sie eine neue set -Anweisung ausgeben, um den Wert zurückzusetzen.

Da jedoch nur ein Superuser dies ändern darf, ist dies wahrscheinlich keine gute Lösung, da Ihr Anwendungsbenutzer dieses Privileg haben müsste, was ein großes Sicherheitsproblem darstellt.

    
a_horse_with_no_name 12.09.2012 10:18
quelle
0

Wenn Sie diese Fehler nur unterdrücken möchten, während Sie in psql arbeiten, können Sie

ausführen %Vor%

, die für den Rest Ihrer Sitzung dauern wird.

    
Randall 28.09.2016 16:25
quelle