2016-11-04 3 views
0

Ich habe eine Spring-Boot-Anwendung und habe einen Webservice, wo ein Benutzer ein Modell einer CollegeCourse-Instanz POSTIEREN kann, die Links zwischen dieser Klasse und den Studenten, die sie nehmen, enthält. (Die Daten werden zum Speichern von Zeilen in der Zuordnungstabelle verwendet, da diese Klassen eine Viele-zu-Viele-Beziehung haben.) Dies funktioniert einwandfrei.Kann ich einen Teil einer @Transactional Sequenz festlegen?

Sagen Sie, dass die Einschreibung in den Kurs ändert. Der Benutzer erwartet, dieselbe JSON-Struktur an den Webservice zu senden, der den PUT-Aufruf behandelt. Der Code nahm den einfachen Weg zum Aktualisieren, indem er zuerst alle vorhandenen CollegeCourse-Student-Links fand und löschte und dann die neuen Links speicherte. (Anstatt die beiden Listen zu durchlaufen, passen die Artikel zusammen.) Dieser Teil funktionierte auch wie angegeben.

Wir haben dann eine Eindeutigkeitseinschränkung zu der CollegeCourse-Student-Zuordnungstabelle hinzugefügt, so dass die Tabelle keinen einzelnen Student mehrfach mit einem CollegeCourse verknüpft haben konnte. Dies stürzte und brannte. Eine Debugging-Sitzung enthüllte den Schuldigen: Das Löschen der CollegeCourse-Student-Datensätze löschte sie nicht wirklich aus der Datenbank, bis die Transaktion abgeschlossen war. Als wir versuchten, die neuen Links wieder einzufügen, kollidierten alle Überbleibsel aus dem ursprünglichen POST mit dem, was bereits in der Datenbank war.

Dem Service, der den PUT behandelt, wird eine @Transactional Annotation vorangestellt. Ich versuchte, den Code zu verschieben, um die Zuordnungen in einer separaten Methode zu finden und zu löschen, und versuchte sowohl @Transactional (propagation = Propagation.REQUIRED) als auch REQUIRES_NEW, verhinderte jedoch nicht, dass die Eindeutigkeitsbeschränkung fehlschlug. Ich habe auch @EnableTransactionManagement zu meiner Application-Klasse hinzugefügt - die gleiche Geschichte. Gibt es eine einfache Lösung für mein Dilemma?

+0

Um Ihr Problem vollständig zu verstehen, wäre es hilfreich mit ein paar Codeschnipsel, die die Methoden veranschaulichen, die zusammen mit den '@ Transactional'-Annotation (en) ins Spiel kommen. –

Antwort

0

Ohne genau zu wissen, wie Ihr Repository aussieht, haben Sie nach dem Löschen versucht, einen manuellen Flush für den Entity Manager durchzuführen?

Etwas nach dem Vorbild von

entityManager.flush(); 

Oder, wenn Sie eine Spring Data JPA-Repository verwenden, sollten Sie in der Lage sein, eine Flush-Methode in dieser Schnittstelle zu definieren, und es nennt.

+0

Ich habe meinem Repository die Flush-Methode hinzugefügt (basierend auf CrudRepository), und das erlaubt es, als interne Transaktion zu laufen. Ich überprüfe Montag, um zu überprüfen, dass die äußere Transaktion noch aktiv ist, und kann im Falle anderer Fehler zurückgesetzt werden. – LitterWalker

Verwandte Themen