Zunächst sollten Sie verstehen, dass die Ursache des Problems keine Transaktion ist. Wir haben eine Transaktion und einen dauerhaften Kontext (Sitzung). Mit @Transactional
Anmerkung Spring erstellt eine Transaktion und öffnet einen persistenten Kontext. Nachdem die Methode aufgerufen wurde, wird ein persistenter Kontext geschlossen.
Wenn Sie ein user.getUserAccount()
aufrufen Sie haben eine Proxy-Klasse, die UserAccount
umschließt (wenn Sie UserAccount
nicht laden mit User
). Wenn also ein persistenter Kontext geschlossen wird, haben Sie eine LazyInitializationException
während des Aufrufs einer beliebigen Methode von UserAccount
, zum Beispiel user.getUserAccount().toString()
.
@Transactional
arbeitet nur auf dem userService
Ebene, in Ihrem Fall. Um @Transactional
zu erhalten funktioniert, reicht es nicht aus, @Transactional
zu setzen Anmerkung zu einer Methode. Sie müssen ein Objekt einer Klasse mit der Methode aus einem Spring Context
erhalten . Um Geld zu aktualisieren, können Sie also eine andere Servicemethode verwenden, zum Beispiel updateMoney(userId, amount)
.
Wenn Sie @Transactional
verwenden möchten Bei der Controller-Methode müssen Sie einen Controller aus Spring Context
abrufen . Und Spring sollte verstehen, dass es jeden @Transactional
umschließen sollte -Methode mit einer speziellen Methode zum Öffnen und Schließen eines persistenten Kontexts. Eine andere Möglichkeit besteht darin, das Session-Per-Request-Anti-Pattern zu verwenden. Sie müssen einen speziellen HTTP-Filter hinzufügen.
https://vladmihalcea.com/the-open-session- in-view-anti-pattern/