2008-09-07 37 views
7

Thiết kế của chúng tôi có một jvm là một jboss/webapp (đọc/ghi) được sử dụng để duy trì dữ liệu qua hibernate (sử dụng jpa) đến db. Mô hình này có 10-15 lớp học liên tục với 3-5 mức độ sâu trong các mối quan hệ.Làm thế nào để duy trì tính ổn định cache Hibernate chạy hai ứng dụng Java?

Sau đó chúng tôi có một jvm riêng biệt là máy chủ sử dụng dữ liệu này. Vì nó đang chạy liên tục, chúng tôi chỉ có một phiên db dài (chỉ đọc).

Hiện tại không có bộ nhớ cache trong-jvm có liên quan - vì vậy chúng tôi sẽ ghi một cách thủ công một jvm từ bộ nhớ cache kia.

Bây giờ khi webapp thay đổi một số dữ liệu, nó báo hiệu máy chủ tải lại dữ liệu đã thay đổi. Những gì chúng tôi đã tìm thấy là chúng ta cần phải nói với hibernate để thanh lọc dữ liệu và sau đó tải lại nó. Chỉ cần thực hiện tìm nạp/hợp nhất với db không thực hiện công việc - chủ yếu là đối với các đối tượng một vài lớp trong hệ thống phân cấp.

Bất kỳ ý tưởng nào về việc có bất kỳ điều gì sai về cơ bản với thiết kế này hay không hoặc có ai làm điều này và đã có may mắn hơn khi làm việc với ngủ đông khi tải lại.

Cảm ơn, Chris

Trả lời

10

Phiên Hibernate tải tất cả dữ liệu mà nó đọc từ DB vào thứ mà họ gọi là bộ nhớ cache cấp một. Khi một hàng được tải từ DB, mọi lần tìm nạp tiếp theo cho một hàng có cùng một PK sẽ trả về dữ liệu từ bộ nhớ cache này. Hơn nữa, Haurnate gaurentees tham khảo bình đẳng cho các đối tượng với cùng một PK trong một phiên duy nhất.

Từ những gì tôi hiểu, ứng dụng máy chủ chỉ đọc của bạn không bao giờ đóng phiên Hibernate. Vì vậy, khi DB được cập nhật bởi ứng dụng đọc-ghi, Session trên máy chủ chỉ đọc không biết gì về sự thay đổi. Có hiệu quả, ứng dụng chỉ đọc của bạn đang tải một bản sao trong bộ nhớ của cơ sở dữ liệu và sử dụng bản sao đó, sẽ bị lỗi thời trong khóa học.

Hành động đơn giản và tốt nhất tôi có thể đề xuất là đóng và mở Phiên khi cần. Điều này sẽ tránh được toàn bộ vấn đề. Các phiên Hibernate được dự định là một cửa sổ cho một tương tác ngắn ngủi với DB. Tôi đồng ý rằng có một hiệu suất đạt được bằng cách không tải lại đồ thị đối tượng một lần nữa và một lần nữa; nhưng bạn cần phải đo lường nó và thuyết phục bản thân rằng đó là giá trị đau.

Một tùy chọn khác là đóng và mở lại phiên theo định kỳ. Điều này đảm bảo rằng ứng dụng chỉ đọc hoạt động với dữ liệu không cũ hơn một khoảng thời gian nhất định. Nhưng chắc chắn là một cửa sổ nơi ứng dụng chỉ đọc hoạt động với dữ liệu cũ (mặc dù thiết kế đảm bảo rằng nó nhận được dữ liệu cập nhật cuối cùng). Điều này có thể được cho phép trong nhiều ứng dụng - bạn cần phải đánh giá tình hình của mình.

Tùy chọn thứ ba là sử dụng bộ nhớ cache cấp thứ hai triển khai và sử dụng Phiên có thời gian sống ngắn. Có nhiều gói bộ nhớ đệm khác nhau hoạt động với Hibernate với các giá trị và mức độ tương đối tương đối.

+0

Sử dụng JPA, và @PersistenceContext để có được những EntityManager - nhưng có vẻ như chúng ta cần @PersistenceUnit cho một EntityManagerFactory và để làm mới dữ liệu, chúng ta có được một EntityManager mới. Nghe có vẻ tốt - nhưng cách tay nặng để cập nhật mọi thứ, nhưng nếu đó là điều mọi người làm ... –

3

Chris, tôi là một chút nhầm lẫn về hoàn cảnh của bạn. Nếu tôi hiểu chính xác, bạn có cả ứng dụng web (đọc/ghi) một ứng dụng độc lập (chỉ đọc?) Sử dụng Hibernate để truy cập cơ sở dữ liệu được chia sẻ. Những thay đổi bạn thực hiện với ứng dụng web không hiển thị với ứng dụng độc lập. Có đúng không?

Nếu có, bạn có cân nhắc sử dụng triển khai bộ nhớ cache cấp hai khác không? Tôi tự hỏi liệu bạn có thể sử dụng bộ nhớ cache nhóm được chia sẻ bởi cả ứng dụng web và ứng dụng độc lập. Tôi tin rằng SwarmCache, được tích hợp với Hibernate, sẽ cho phép điều này, nhưng tôi đã không thử nó bản thân mình.

Nói chung, bạn nên biết rằng nội dung của một bộ nhớ cache nhất định sẽ không bao giờ biết hoạt động của ứng dụng khác (đó là lý do tại sao tôi đề nghị cả hai ứng dụng chia sẻ bộ nhớ cache). Chúc may mắn!

2

Từ quan điểm của tôi, bạn nên thay đổi bộ đệm ẩn Hibernate dưới dạng của bạn thành bộ nhớ cache hỗ trợ chế độ nhóm. Nó có thể là JBoss Cache hoặc Swarm Cache. Việc đầu tiên có một sự hỗ trợ tốt hơn của đồng bộ hóa dữ liệu (nhân rộng và vô hiệu hóa) và cũng hỗ trợ JTA.

Sau đó, bạn sẽ có thể định cấu hình đồng bộ hóa bộ nhớ cache giữa webapp và máy chủ. Ngoài ra nhìn vào mức cô lập nếu bạn sẽ sử dụng JBoss Cache. Tôi tin rằng bạn nên sử dụng chế độ READ_COMMITTED nếu bạn muốn nhận dữ liệu mới trên máy chủ từ cùng một phiên.

1

Thực tiễn được sử dụng nhiều nhất là có Container-Managed Entity Manager để hai hoặc nhiều ứng dụng trong cùng một vùng chứa (ví dụ Glassfish, Tomcat, Websphere) có thể chia sẻ cùng một bộ nhớ cache. Nhưng nếu bạn không sử dụng vùng chứa Ứng dụng, vì bạn sử dụng Play! ví dụ, sau đó tôi sẽ xây dựng một số dịch vụ web trong ứng dụng chính chính để đọc/ghi một cách nhất quán trong bộ nhớ cache.

Tôi nghĩ rằng việc sử dụng dữ liệu cũ là một cánh cửa mở cho thiên tai. Giống như Singletons trở thành Multitons, các ứng dụng chỉ đọc thường là viết đôi khi.

đai và niềng răng :)

Các vấn đề liên quan