Trigger vs. JPA @PrePersist für die Erstellung und Aktualisierung von Zeitstempeln Pro und Contra

8

Ich baue eine neue Web-App und verwende Spring, JPA / Hibernate und Postgres. Einige meiner Tabellen haben creation_ts- und lastupdate_ts-Spalten, bei denen es sich um Zeitstempelspalten handelt, die verfolgen, wann eine Einfügung stattgefunden hat und wann die letzte Aktualisierung in einer Zeile aufgetreten ist.

Ich verwende auch eine Namenskonvention für Spalten in meinen Tabellen. Aus Gründen der Design-Richtlinie hat jede Tabelle garantiert zwei Spalten: pkey ist ein Integer-Ersatzschlüssel und Version für optimistisches Sperren.

Ich habe zwei Möglichkeiten, diese Felder aktuell zu halten.

Option A: Verwenden Sie Trigger

Dies ist die Lösung, die ich gerade eingerichtet habe, ich habe zwei Postgres-Trigger, die auf Einfügen und Update feuern und diese Felder auf dem neuesten Stand halten. und ich habe zwei Klassen.

%Vor%

und ich habe

%Vor%

Option B: Verwenden Sie JPA-Listener

In dieser Option würde ich JPA-Listener verwenden, um die Zeitstempelspalten auf dem neuesten Stand zu halten.

Meine Frage:

Welcher dieser beiden Ansätze ist besser? Wie ich die Dinge hier sehe, ist meine persönliche Liste der Vor- und Nachteile jeder Option und ich sehr daran interessiert, die Erfahrung anderer mit diesen beiden Möglichkeiten zu hören.

Option A Profis:

  1. Die Datenbank führt die Aktualisierungen mit den Triggern durch, sodass keine Gefahr besteht, dass der Cluster in der Webanwendung klemmt.
  2. Wenn eine Nicht-JPA-Anwendung auf die Datenbank zugreift, wird die Anforderung, diese beiden Spalten beizubehalten, erzwungen.

Option A Nachteile:

  1. Nach der Einfügung und Aktualisierung müssen Sie eine Auswahl treffen, um die Werte zu lesen, die die Auslöser setzen.
  2. Ich verwende Hibernate-Annotationen, um die Werte
  3. zurückzulesen

Option B Pro:

  1. Weniger Tippen beim Erstellen der DDL
  2. Nach dem Einfügen und Aktualisieren müssen Sie keine Werte aus der Datenbank zurücklesen
  3. Reine JPA-Anmerkungen, keine spezifischen Anmerkungen im Winterschlaf

Option B Nachteile:

  1. Gefahr der Taktverschiebung im Cluster
  2. Felder, die festgelegt werden, wenn der JPA-Anbieter entscheidet, die Rückrufmethoden nicht vorhersehbar aufzurufen

Wie würden Sie dieses Problem für eine neue App lösen, in der Sie die totale Kontrolle über die Datenbank und den Java-Code haben.

    
ams 09.03.2011, 16:39
quelle

3 Antworten

6
  

Mache nach dem Einfügen eine Auswahl und aktualisiere, um die Werte zu lesen, die die Trigger setzen.

Sie können INSERT ... RETURNING oder UPDATE ... RETURNING verwenden, um die Werte abzurufen, die durch den Trigger geändert wurden, sodass keine weitere SELECT-Operation erforderlich ist.

Abgesehen davon würde ich sagen, dass es von Ihrer Umgebung abhängt. Wenn die Anwendung missionskritisch ist und kläglich versagt, wenn diese Spalten nicht korrekt verwaltet werden, würde ich bei den Triggern bleiben.

Wenn dies nur der Einfachheit halber im Frontend verwendet wird (und Konflikte aufgrund falscher Werte korrekt behandelt werden können), ist der JPA-Ansatz wahrscheinlich leichter zu pflegen.

    
a_horse_with_no_name 09.03.2011, 16:47
quelle
1
  

Gefahr der Taktverschiebung im Cluster

Ich würde sagen, ich sollte mir darüber keine Sorgen machen. Es kann im Cluster genau so ausfallen, wie es in der Datenbank fehlschlagen könnte. In einer richtigen Produktionsumgebung hätten Sie Ihre eigenen NTP-Server, und Ihr Cluster würde damit synchronisiert.

Ich bevorzuge es, alles in Java zu behalten, da ein zentraler Ort für "Logik" (für mich) wünschenswert ist. Das Platzieren von Logik in Triggern ist akzeptabel, wenn Sie nicht-Java-Anwendungen verwenden.

    
jpkrohling 09.03.2011 17:13
quelle
1

Ich verwende Option A (mit all Ihren Frameworks und PostgreSQL) zur Zeit wie folgt:

%Vor%

Wenn Sie die columnDefinition wie im Code beschrieben verwenden, müssen Sie das Objekt nicht erneut auswählen und auch keinen Code schreiben, um das Datum für Ihre Objekte festzulegen. Ich habe nie die JPA-Callbacks verwendet, außer Envers Framework zu verbinden, aber ich kann sagen, es sieht zu viel Aufwand nur um das Datum auf bestimmte Objekte zu setzen.

    
Lucas de Oliveira 09.03.2011 17:33
quelle