2011-12-02 37 views
8

Tôi đang làm việc với một ứng dụng web Grails và tôi nhận được rất nhiều điều kỳ lạ khi sử dụng dịch vụ Grails. Vì vậy, tôi muốn hỏi một số câu hỏi về điều này để làm cho tôi hiểu thêm về các dịch vụ của Grails. Điều này sẽ rất hữu ích cho tôi (và có thể cho những người khác^_ ^). Cảm ơn trước.Một số câu hỏi về dịch vụ Grails

  1. Nếu dịch vụ được định cấu hình với giao dịch tĩnh = true, nó sẽ xóa mọi dữ liệu thay đổi thành DB sau khi phương thức nào bị bẩn và bị khóa trong phiên Hibernate?

  2. Tôi có thể sử dụng chú thích @Transactional ở cấp lớp thay vì static transactional = true không? Và là nó possbile để đặt @Transactional(readOnly = true) tại một số phương pháp mà tôi chỉ muốn họ đọc (truy vấn, tìm) dữ liệu từ DB?

  3. Làm thế nào về kế thừa giao dịch? Ý tôi là, nếu dịch vụ cha mẹ được cấu hình static transactional = true và dịch vụ con có chú thích @Transactional (trên lớp) và một số @Transactional(readOnly = true) (trên một số phương pháp), điều gì sẽ xảy ra nếu tôi gọi phương thức từ cha mẹ?

  4. Giao dịch có hoạt động với dịch vụ trừu tượng không? Bởi vì như tôi đã biết, với dịch vụ trừu tượng, chúng ta không thể khởi tạo bean của nó, và có thể khi bắt đầu ứng dụng, có một số khác biệt trong ngữ cảnh Grails.

Trả lời

7

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()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

+0

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? –