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.
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. Bitte helfen Sie.
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.
Tags und Links jpa insert-update