Wie zu beheben StaleObjectStateException mit JPA und Hibernate
Controller-Logik:
def updateObject() {
Object o = Object.get(params.id as Long)
o.otherObjects.clear()
objectDataService.saveObject(o.id)
OtherObject newObject = new OtherObject;
o.addToOtherObjects(newObject)
objectDataService.saveObject(o.id)
}
ServiceLogic
def saveObject(long profileId) {
o.save(flush:true)
}
was passiert
in 90% der Fälle wird dies nur funktionieren.
Probleme
ERROR errors.GrailsExceptionResolver - StaleObjectStateException occurred when processing request: [GET] /controller/updateObject - parameters:
stuff[]: data
Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect) : [com.path.Object#1].
Stacktrace follows:
Message: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect) : [com.path.Object#1]
habe ich gelesen, durch Fragen und fand die merge
aufrufen, sehen Sie oben. es löste über 50% der Fälle, aber nicht alle.
- wäre es nicht besser hier, wenn Sie verschoben diese Logik in einem service-Methode so alles unter der gleichen Transaktion?
- ich will nicht, um eine überlastung des service. glaubst du, es würde Sinn machen?
- Es ist immer besser, sich zu bewegen, die business-Logik zu Diensten und machen Sie Ihren Controller so Dünn wie möglich (mit Dünn meine ich mit weniger code-Zeilen). Dies wird Ihnen helfen, die Wiederverwendung von code, wo immer erforderlich, und Sie sparen eine Menge Zeit in Tests als gut.
- Erwarten Sie, dass gleichzeitige Zugriffe auf diese Aktion, die von vielen Benutzern oder nur ein Benutzer auf die Aktion mehr als einmal?
- es ist derzeit nur selber testen. keine gleichzeitige Benutzer (alle auf localhost)
Du musst angemeldet sein, um einen Kommentar abzugeben.
StaleObjectStateException:
Diese lösen werden können, wie.
Über @version:
Hier die version-Eigenschaft zugeordnet ist OPTLOCK Spalte und den entity-manager verwendet es um zu erkennen widersprüchliche updates, und verhindern den Verlust von updates, würde überschrieben werden durch ein last commit wins-Strategie @version
Für mehr Details Grails-siehe link unten , es ist mit der Git-hub-code.
test für GRAILS-8937: HibernateOptimisticLockingFailureexception
Den StaleObjectStateException können auftreten, die natürlich auf jedes andere Projekt. Jedes mal, wenn zwei Transaktionen gleichzeitig geladen werden, die gleiche Person version und jedes dieser änderung, die Person, die Sie am Ende mit der letzten ausgeführten thread zu scheitern, durch eine optimistische locking-Kollision scheitern.
In Ihrem Fall gibt es eine extra anrufen, außerhalb der JPA-Grenzen, das kann Erleichterung dieser Ausgabe:
Jede Transaktion ist thread-gebunden und es passiert in einer Session, so dass zwei konkurrierende threads wird über zwei Objekt-Referenzen für die gleiche Person id. Das optimistische locking Ziel arbeitet effektiv, ohne andere explizite locking-Mechanismus.
Wenn Sie senden Sie die geänderte entity-Referenz für die
saveObject
version und erhalten Sie noch diese Ausnahme, es heißt, Sie haben eine hohe chance für zwei konkurrierende threads zu ändern, die gleichen Entitäten.In diesem Szenario eine pessimistische sperren wird zu besseren Resultaten führen, da es sich um das warten im Gegensatz zu den optimistisch fail-fast-Ansatz.
Uns ein paar verschiedene Ansätze schließlich löste das StaleObjectException auftreten regelmäßig:
erfrischende Objekte nach dem abrufen Sie lösten die meisten unserer StaleObjectExceptions. Vor allem in Fällen, in denen die Möglichkeit Bestand, dass jemand würde gearbeitet haben, auf das gleiche Objekt von woanders und verändert einige seiner Mitglieder (die meisten Probleme kamen mit der Sammlung Mitglieder).
Gesamtprojekt Stabilität:
hatten wir ein 404 auf eine bestimmte Ressource-Datei, die wir eigentlich gar nicht brauchen und wird daher ignoriert, es für einige Zeit. stellt sich heraus, dass die fehlende Datei würde dazu führen, die Sitzung zu offen gehalten werden - also die Herstellung StaleObjects Links und rechts.
Daher als ein Hinweis auf jemand gerichtete mehr als die üblichen (einige StaleObjects können immer auftreten - siehe obige Antworten) StaleObjectExceptions: Stellen Sie sicher, dass alle Ressourcen korrekt verlinkt sind und Ihre developer tools (Chrome F12) nicht, melden Sie alle fehlenden Dateien.