2009-10-31 5 views
5

Tôi thực sự bối rối về tuyên truyền giao dịch trong Spring with Hibernate. Tôi sử dụng chú thích Spring @Transactional trên các phương thức lớp dịch vụ của mình. Một số được đánh dấu là 'read-only = true'. Nếu một trong các phương thức dịch vụ chỉ đọc của tôi gọi một phương thức không chỉ đọc, tôi có thể giải quyết vấn đề này bằng cách nào? Tôi nghĩ tôi có thể đánh dấu tất cả các phương pháp đọc-ghi của mình để hỗ trợ tuyên truyền REQUIRES_NEW nhưng điều này sẽ dẫn đến hành vi mà tôi có thể không muốn - tức là tôi chỉ muốn một giao dịch mới trong trường hợp phương pháp chỉ đọc là được gọi là phương pháp đọc-ghi. Nếu phương thức đọc-ghi gọi phương thức đọc-ghi khác, tôi sẽ không cần giao dịch mới.Truyền thông giao dịch hoạt động như thế nào khi sử dụng Phiên mở trong chế độ xem?

Cân nhắc tất cả những điều này, tôi không hiểu cách Open Session In View (OSIV) hoạt động như thế nào! Chắc chắn, bằng cách sử dụng OSIV trong mùa xuân, các OpenSessionInViewFilter phải có để bắt đầu một giao dịch trước khi các phương pháp dịch vụ được gọi. Trong trường hợp đó, nó phải xác định xem giao dịch là chỉ đọc hoặc đọc-ghi. NHƯNG, làm thế nào nó có thể biết điều này? Nó không biết điều gì sẽ xảy ra dưới lớp phủ của lớp dịch vụ.

Tôi hoàn toàn trong bóng tối trên tất cả những điều này và sẽ yêu ai đó giải thích cho tôi!

Trả lời

2

Mở phiên trong chế độ xem không yêu cầu toàn bộ yêu cầu xảy ra trong một giao dịch duy nhất, nó chỉ có nghĩa là phiên Hibernate được gắn với Chủ đề phân phối yêu cầu và sử dụng lại mọi lúc. yêu cầu. Hãy nhớ rằng một Session giống như một bản đồ ưa thích duy trì danh tính của tất cả các đối tượng được ánh xạ trong phạm vi của nó, các đối tượng thực tế có thể được tìm nạp trong một giao dịch hoặc trong nhiều giao dịch.

Mẫu phiên trên mỗi giao dịch thực sự là thay thế thành OSIV. Mẫu này thường không gặp phải. Tại điểm của phương pháp chỉ đọc của bạn, gọi phương thức đọc-ghi, tôi sẽ nói rằng bạn nên nghĩ lại lý do tại sao bạn muốn xem xét chỉ đọc này khi thực tế nó có thể ghi dữ liệu. Tôi sẽ lập luận rằng bạn hoặc là yếu tố ra phần chỉ đọc và có một phương pháp đọc-ghi gọi một phương pháp chỉ đọc, hoặc rằng bạn chỉ dừng lại xem xét nó chỉ đọc (nó không phải là).

Chỉ vì giao dịch được đưa vào chế độ chỉ đọc cho một giao dịch, không có nghĩa là giao dịch sẽ vẫn ở chế độ chỉ đọc cho phần còn lại của Phạm vi phiên (OSIV). Trong thực tế, các giao dịch tiếp theo trong phạm vi Phiên mở có thể thậm chí không xảy ra trên cùng một kết nối.

2

Nếu bạn gọi phương thức giao dịch đọc-đọc từ phương thức giao dịch chỉ đọc, thì trạng thái chỉ đọc sẽ lan truyền. I E. toàn bộ giao dịch sẽ là chỉ đọc. Bạn có thể muốn thay đổi phương thức gọi của bạn thành đọc-ghi, bởi vì giao dịch thực sự được coi là đọc-ghi.

Hoặc bạn có thể sử dụng tuyên truyền REQUIRES_NEW nhưng trong trường hợp đó, Spring sẽ tạo một phiên khác cho toàn bộ thời gian của giao dịch mới. Chỉ sử dụng nếu giao dịch mới thực sự cần thiết.

Phiên Hibernate có thể chứa một số giao dịch tuần tự. Vì vậy, bộ lọc OSIV không cần biết loại giao dịch nào sẽ chứa. Bộ lọc OSIV tạo phiên với phương thức FlushMode = MANUAL và đọc-ghi sẽ thay đổi tạm thời thành FlushMode = AUTO. Mỗi giao dịch sẽ sử dụng kết nối JDBC chỉ đọc hoặc đọc-ghi.

6

Vòng đời của các phiên Hibernate khác với phiên giao dịch. Hai người có thể chồng lên nhau.

Trong trường hợp OpenSessionInViewFilter, điều này không liên quan gì đến giao dịch, nó chỉ quản lý vòng đời của phiên Hibernate trong khi yêu cầu. Khi một phương thức Spring-transactional được gọi, một giao dịch mới được bắt đầu và kết hợp với phiên ngủ đông, và sau đó cam kết/cuộn lại khi phương thức thoát. Sau đó, phiên sẽ được bộ lọc đóng khi yêu cầu hoàn tất. Không cần phải bắt đầu/kết thúc giao dịch cùng lúc với phiên.

Đối với câu hỏi giao dịch read-only của bạn (đây là vấn đề khác hoàn toàn), đây thực sự không phải là một gợi ý cho cơ sở dữ liệu bên dưới mà không có dữ liệu nào bị sửa đổi. Tôi chưa bao giờ thấy điều này có bất kỳ hiệu ứng cụ thể, mặc dù, nó có vẻ là hữu ích hơn như một công cụ tài liệu hơn bất cứ điều gì khác.