Es gibt in der Tat zwei Möglichkeiten, dies zu erreichen:
-
Test, ob ein Datensatz existiert, bevor er --innerhalb derselben Transaktion--eingefügt wird.
-
Bestimmen Sie, ob SQLException#getSQLState()
der gefangenen SQLException
beginnt mit 23
was einen Verstoß gegen die Beschränkung gemäß der SQL-Spezifikation . Es können nämlich mehr Faktoren als "nur" ein Verstoß gegen eine Einschränkung die Ursache sein. Sie sollten nicht jede SQLException
als einen Verstoß gegen eine Beschränkung.
public static boolean isConstraintViolation(SQLException e) {
return e.getSQLState().startsWith("23");
}
Ich würde mich für die erste Variante entscheiden, da sie semantisch korrekter ist. Es handelt sich in der Tat nicht um einen außergewöhnlichen Umstand. Sie haben nämlich wissen dass es möglicherweise dazu kommen wird. In einer stark konkurrierenden Umgebung, in der Transaktionen nicht synchronisiert werden (entweder aus Unwissenheit oder um die Leistung zu optimieren), kann es jedoch zu Fehlern kommen. In diesem Fall möchten Sie vielleicht stattdessen die Ausnahme ermitteln.
Abgesehen davon sollten Sie normalerweise keine Einschränkungsverletzung bei einer Primärschlüssel . In gut konzipierten Datenmodellen, die technische Schlüssel als Primärschlüssel verwenden, sind diese normalerweise von der Datenbank selbst zu verwalten. Sollte das Feld nicht ein eindeutiger Schlüssel ?