Bạn nên hỏi một câu hỏi mỗi câu hỏi :)
Đối với câu hỏi # 1, vâng - Spring/Hibernate tích hợp đảm bảo rằng một tuôn ra xảy ra trước khi cam kết. Vì vậy, các cuộc gọi đến save()
và delete()
sẽ bị xóa và không cần phải thêm flush: true
vào một trong hai. Ngoài ra, các trường hợp bẩn mà bạn chưa gọi là save()
cũng sẽ bị xóa, trừ khi bạn gọi discard()
.
Đối với # 2: Dịch vụ được giao dịch theo mặc định, vì vậy transactional = true
thực sự là dự phòng - bạn chỉ cần chỉ định nó để nói transactional = false
. Nhưng trình bao bọc giao dịch tự động được tạo chỉ được thực hiện nếu không có chú thích @Transactional
. Nếu bạn có một hoặc nhiều chú thích thì các định nghĩa đó sẽ xác định ranh giới giao dịch. Vì vậy, theo mặc định (nghĩa là không có chú thích nào và không có thuộc tính transactional
hoặc transactional = true
), tất cả các phương thức đều giao dịch, nhưng nếu bạn chỉ chú thích một tập hợp con của các phương thức thì chỉ những chú thích đó sẽ được giao dịch.
Thông thường bạn sẽ sử dụng chú thích khi bạn muốn hành vi không mặc định, tức là tuyên truyền, cô lập, hết giờ, v.v. (hoặc biến nó thành chỉ đọc như trong ví dụ của bạn).
Bạn có thể chú thích ở cấp lớp để có cùng cấu hình cho tất cả các phương pháp và tùy chọn chú thích các phương thức riêng lẻ để ghi đè lên các giá trị mặc định của phạm vi lớp.
Đối với # 3 và # 4, các quy tắc chuẩn áp dụng (xem # 2). Nếu lớp con có chú thích, thì transactional = true
từ lớp đó hoặc lớp cha mẹ sẽ bị bỏ qua vì bằng cách sử dụng chú thích bạn đã nói với Grails rằng bạn đang định cấu hình mọi thứ.
Vì các dịch vụ trừu tượng không thể được khởi tạo, lớp con cụ thể thực sự được khởi tạo sẽ có hành vi kết hợp từ lớp cơ sở và chính nó. Nếu mọi thứ là transactional = true
thì nó đơn giản và nếu bạn có bất kỳ chú thích nào thì chúng sẽ xác định các quy tắc.
Các phương thức gọi trong siêu lớp sẽ hoạt động giống như các phương thức gọi trong lớp hiện tại. Nhưng hành vi này là một chút phản trực giác nếu bạn không xem xét các tác động của phương pháp proxy của Spring. Khi bạn gọi một phương thức giao dịch, proxy chặn cuộc gọi và tham gia giao dịch đang hoạt động hoặc bắt đầu một giao dịch mới nếu cần hoặc bắt đầu một giao dịch mới nếu REQUIRES_NEW được chỉ định. Nhưng một khi bạn đang ở trong lớp thực và gọi một phương pháp khác, bạn sẽ bỏ qua proxy. Vì vậy, nếu bạn gọi một phương thức khác với các cài đặt chú thích khác nhau, chúng sẽ bị bỏ qua. Nếu bạn định làm điều đó, hãy xem thảo luận về danh sách gửi thư này về những gì đang diễn ra và cách làm việc với nó: http://grails.1312388.n4.nabble.com/non-transactional-service-extends-transactional-service-outcome-td3619420.html
Tuyệt vời! Cảm ơn bạn rất nhiều vì câu trả lời rõ ràng của bạn. Nhưng chúng ta hãy xem xét điểm 3 với ngược lại: dịch vụ cha mẹ A được đánh dấu @Annotation trên cấp lớp và phương thức doParent() trong A là readOnly = true, trong khi dịch vụ con B không có bất kỳ cấu hình cụ thể nào về giao dịch. Tại sao tôi gọi doParent() từ B, nó vẫn còn tuôn ra dữ liệu mặc dù tôi buộc nó readOnly? –