Thứ nhất, bạn nên hiểu rằng gốc rễ của vấn đề không phải là một giao dịch. Chúng ta có một giao dịch và một bối cảnh liên tục (phiên). Với @Transactional
chú thích Mùa xuân tạo ra một giao dịch và mở ngữ cảnh liên tục. Sau khi phương thức được gọi, một ngữ cảnh liên tục sẽ bị đóng.
Khi bạn gọi một user.getUserAccount()
bạn có một lớp proxy bao bọc UserAccount
(nếu bạn không tải UserAccount
với User
). Vì vậy, khi một ngữ cảnh liên tục bị đóng, bạn có LazyInitializationException
trong khi gọi bất kỳ phương thức nào của UserAccount
, ví dụ user.getUserAccount().toString()
.
@Transactional
chỉ hoạt động trên userService
trong trường hợp của bạn. Để nhận @Transactional
hoạt động, chỉ cần đặt @Transactional
là chưa đủ chú thích về một phương thức. Bạn cần lấy một đối tượng của một lớp với phương thức từ Spring Context
. Vì vậy, để cập nhật tiền, bạn có thể sử dụng một phương thức dịch vụ khác, ví dụ:updateMoney(userId, amount)
.
Nếu bạn muốn sử dụng @Transactional
trên phương thức bộ điều khiển, bạn cần lấy bộ điều khiển từ Spring Context
. Và Spring nên hiểu rằng nó sẽ bao bọc mọi @Transactional
phương pháp với một phương pháp đặc biệt để mở và đóng một ngữ cảnh liên tục. Cách khác là sử dụng mẫu Chống phiên mỗi yêu cầu. Bạn sẽ cần thêm một bộ lọc HTTP đặc biệt.
https://vladmihalcea.com/the-open-session- in-view-anti-pattern /