Първо, трябва да разберете, че коренът на проблема не е транзакция. Имаме транзакция и постоянен контекст (сесия). С @Transactional анотация Spring създава транзакция и отваря постоянен контекст. След като методът бъде извикан, постоянният контекст се затваря.
Когато извикате user.getUserAccount() имате прокси клас, който обвива UserAccount (ако не заредите UserAccount с User ). Така че, когато постоянен контекст е затворен, имате LazyInitializationException по време на извикване на който и да е метод на UserAccount , например user.getUserAccount().toString() .
@Transactional работи само на userService ниво във вашия случай. За да получите @Transactional работа, не е достатъчно да поставите @Transactional анотация върху метод. Трябва да получите обект на клас с метода от Spring Context . Така че, за да актуализирате парите, можете да използвате друг метод на услугата, например updateMoney(userId, amount) .
Ако искате да използвате @Transactional на метода на контролера трябва да получите контролер от Spring Context . И Spring трябва да разбере, че трябва да обвие всеки @Transactional метод със специален метод за отваряне и затваряне на постоянен контекст. Друг начин е да използвате сесия на заявка анти шаблон. Ще трябва да добавите специален HTTP филтър.
https://vladmihalcea.com/the-open-session- in-view-anti-pattern/