PostgreSQL
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> PostgreSQL

Làm thế nào để làm mới các thực thể JPA khi cơ sở dữ liệu phụ trợ thay đổi không đồng bộ?

Tôi khuyên bạn nên thêm một @Startup @Singleton lớp thiết lập kết nối JDBC với cơ sở dữ liệu PostgreSQL và sử dụng LISTENNOTIFY để xử lý tình trạng vô hiệu bộ nhớ cache.

Cập nhật :Đây là một cách tiếp cận thú vị khác, sử dụng pgq và tập hợp các công nhân để làm mất hiệu lực.

Báo hiệu hết hiệu lực

Thêm trình kích hoạt trên bảng đang được cập nhật sẽ gửi NOTIFY bất cứ khi nào một thực thể được cập nhật. Trên PostgreSQL 9.0 trở lên NOTIFY này có thể chứa trọng tải, thường là ID hàng, vì vậy bạn không phải làm mất hiệu lực toàn bộ bộ nhớ cache của mình, chỉ thực thể đã thay đổi. Trên các phiên bản cũ hơn không hỗ trợ tải trọng, bạn có thể thêm các mục nhập không hợp lệ vào bảng nhật ký có dấu thời gian mà lớp trợ giúp của bạn truy vấn khi nhận được NOTIFY hoặc chỉ làm mất hiệu lực của toàn bộ bộ nhớ cache.

Lớp người trợ giúp của bạn bây giờ LISTEN s trên NOTIFY sự kiện mà trình kích hoạt gửi. Khi nó nhận được một NOTIFY sự kiện, nó có thể làm mất hiệu lực các mục nhập bộ nhớ cache riêng lẻ (xem bên dưới) hoặc xóa toàn bộ bộ nhớ cache. Bạn có thể nghe thông báo từ cơ sở dữ liệu với hỗ trợ lắng nghe / thông báo của PgJDBC. Bạn sẽ cần phải mở bất kỳ trình gộp kết nối nào được quản lý java.sql.Connection để đến với triển khai PostgreSQL cơ bản để bạn có thể truyền nó tới org.postgresql.PGConnection và gọi getNotifications() trên đó.

Một giải pháp thay thế cho LISTENNOTIFY , bạn có thể thăm dò ý kiến ​​bảng nhật ký thay đổi trên một bộ đếm thời gian và có một trình kích hoạt trên bảng sự cố nối các ID hàng đã thay đổi và thay đổi dấu thời gian vào bảng nhật ký thay đổi. Cách tiếp cận này sẽ có tính di động ngoại trừ nhu cầu về một trình kích hoạt khác nhau cho từng loại DB, nhưng nó không hiệu quả và ít hợp thời hơn. Nó sẽ yêu cầu bỏ phiếu thường xuyên không hiệu quả và vẫn có thời gian trễ mà phương pháp lắng nghe / thông báo thì không. Trong PostgreSQL, bạn có thể sử dụng UNLOGGED để giảm một chút chi phí của phương pháp này.

Mức bộ nhớ đệm

EclipseLink / JPA có một số cấp độ bộ nhớ đệm.

Bộ nhớ đệm cấp 1 nằm ở EntityManager cấp độ. Nếu một thực thể được đính kèm với một EntityManager bởi persist(...) , merge(...) , find(...) , v.v., rồi đến EntityManager được yêu cầu trả lại cùng một phiên bản của thực thể đó khi nó được truy cập lại trong cùng một phiên, cho dù ứng dụng của bạn có còn tham chiếu đến nó hay không. Phiên bản đính kèm này sẽ không được cập nhật nếu nội dung cơ sở dữ liệu của bạn đã thay đổi.

Bộ nhớ đệm cấp 2, là tùy chọn, nằm ở EntityManagerFactory cấp và là một bộ nhớ cache truyền thống hơn. Không rõ bạn đã bật bộ nhớ cache cấp 2 hay chưa. Kiểm tra nhật ký EclipseLink và persistence.xml của bạn . Bạn có thể truy cập vào bộ đệm ẩn cấp 2 với EntityManagerFactory.getCache(); xem Cache .

@thedayofcondor đã chỉ ra cách xóa bộ nhớ cache cấp 2 bằng:

em.getEntityManagerFactory().getCache().evictAll();

nhưng bạn cũng có thể loại bỏ các đối tượng riêng lẻ bằng evict(java.lang.Class cls, java.lang.Object primaryKey) gọi:

em.getEntityManagerFactory().getCache().evict(theClass, thePrimaryKey);

mà bạn có thể sử dụng từ @Startup của mình @Singleton NOTIFY trình lắng nghe để chỉ vô hiệu hóa những mục nhập đã thay đổi.

Bộ nhớ cache cấp 1 không dễ dàng như vậy, bởi vì nó là một phần của logic ứng dụng của bạn. Bạn sẽ muốn tìm hiểu về cách EntityManager , các thực thể được đính kèm và tách rời, v.v. hoạt động. Một tùy chọn là luôn sử dụng các thực thể tách rời cho bảng được đề cập, trong đó bạn sử dụng một EntityManager mới bất cứ khi nào bạn tìm nạp thực thể. Câu hỏi này:

Phiên JPA EntityManager không hợp lệ

có một cuộc thảo luận hữu ích về việc xử lý sự vô hiệu của bộ nhớ cache của trình quản lý thực thể. Tuy nhiên, không chắc là một EntityManager bộ nhớ cache là vấn đề của bạn, vì dịch vụ web RESTful thường được triển khai bằng cách sử dụng EntityManager ngắn các phiên họp. Đây chỉ có thể là sự cố nếu bạn đang sử dụng ngữ cảnh liên tục kéo dài hoặc nếu bạn đang tạo và quản lý EntityManager của riêng mình các phiên thay vì sử dụng tính ổn định do vùng chứa quản lý.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. PostgreSQL khác gì với MySQL?

  2. Làm cách nào để thực hiện truy vấn không phân biệt chữ hoa chữ thường trong Postgresql?

  3. Tại sao pg_restore trả về thành công nhưng không thực sự khôi phục cơ sở dữ liệu của tôi?

  4. Cách khởi động Máy chủ PostgreSQL trên Mac OS X qua Homebrew

  5. múi giờ mặc định của postgres