Erstellen Sie neue Entitäten oder aktualisieren Sie bestehende Entitäten auf einmal mit JPA

9

A hat eine JPA-Entität, die ein Zeitstempelfeld hat und durch ein Feld mit einem komplexen Bezeichner unterschieden wird. Was ich brauche, ist Zeitstempel in einer Entität zu aktualisieren, die bereits gespeichert wurde, andernfalls erstellen und speichern Sie neue Entität mit dem aktuellen Zeitstempel.

Wie sich herausstellt, ist die Aufgabe nicht so einfach, wie es auf den ersten Blick scheint. Das Problem ist, dass ich in der gleichzeitigen Umgebung eine böse "Eindeutige Index- oder Primärschlüsselverletzung" Ausnahme bekomme. Hier ist mein Code:

%Vor%

Bitte beachten Sie, dass in diesem Beispiel die Entitätskennung beim Einfügen nicht erzeugt wird, sie ist im Voraus bekannt.

Wenn zwei oder mehr Threads diesen Codeblock parallel ausführen, können sie gleichzeitig null von entityManager.find(Entity.class, id) Methodenaufruf abrufen, sodass sie versuchen, zwei oder mehr Entitäten gleichzeitig mit demselben Bezeichner zu speichern was zu einem Fehler führt.

Ich denke, dass es nur wenige Lösungen für das Problem gibt.

  1. Sicher, ich könnte diesen Codeblock mit einer globalen Sperre synchronisieren, um den gleichzeitigen Zugriff auf die Datenbank zu verhindern, aber wäre das der effizienteste Weg?
  2. Einige Datenbanken unterstützen sehr nützliche MERGE -Anweisungen, die bestehende Dateien aktualisieren oder neue Zeilen erstellen, wenn keine vorhanden sind. Aber ich bezweifle, dass OpenJPA (JPA-Implementierung meiner Wahl) es unterstützt.
  3. Event, wenn JPA SQL MERGE nicht unterstützt, kann ich immer wieder auf normale JDBC zurückgreifen und mit der Datenbank machen, was ich will. Aber ich möchte keine komfortable API verlassen und mit der haarigen JDBC + SQL-Kombination herumspielen.
  4. Es gibt einen magischen Trick, um es nur mit der Standard-JPA-API zu beheben, aber ich weiß es noch nicht.

Bitte helfen Sie.

    
Alex R 25.02.2010, 18:21
quelle

1 Antwort

1

Sie beziehen sich auf die Transaktionsisolation von JPA-Transaktionen. I.e. Wie verhalten sich Transaktionen, wenn sie auf Ressourcen anderer Transaktionen zugreifen?

Nach diesem Artikel :

  

READ_COMMITTED ist die erwartete Standardtransaktionsisolationsstufe für die Verwendung von [..] EJB3 JPA

Dies bedeutet, dass - ja, Sie werden Probleme mit dem obigen Code haben.

Aber JPA unterstützt keine benutzerdefinierten Isolationsstufen.

Dieser Thread behandelt das Thema ausführlicher. Abhängig davon, ob Sie Spring oder EJB verwenden, denke ich, dass Sie die richtige Transaktionsstrategie verwenden können.

    
Bozho 08.03.2010, 09:00
quelle

Tags und Links