Bộ nhớ đệm là tất cả về tối ưu hóa hiệu của suất ứng dụng. Nó nằm giữa ứng dụng và cơ sở dữ liệu để tránh số lượng lượt truy cập cơ sở dữ liệu càng nhiều càng tốt để cung cấp cho một hiệu suất tốt hơn cho các ứng dụng.
Bộ nhớ đệm cũng rất quan trọng đối với Hibernate sử dụng các lược đồ bộ nhớ đệm nhiều cấp như được giải thích dưới đây:
Nội dung chính
Các kiểu bộ nhớ cache trong Hibernate
Có 3 kiểu bộ nhớ cache trong Hibernate đó là: Bộ nhớ cache cấp một (First-level), Bộ nhớ cache cấp hai (Second-level) và Bộ nhớ cache cấp truy vấn.
Bộ nhớ cache cấp một (First-level)
Bộ nhớ cache cấp một là bộ nhớ cache Session và là một bộ nhớ cache bắt buộc thông qua đó tất cả các yêu cầu phải vượt qua. Đối tượng Session giữ một đối tượng thuộc quyền sở hữu của nó trước khi commit nó vào cơ sở dữ liệu.
Nếu bạn phát hành nhiều bản cập nhật cho một đối tượng, Hibernate cố gắng trì hoãn việc cập nhật càng lâu càng tốt để giảm số lượng các câu lệnh SQL cập nhật đã ban hành. Nếu bạn đóng session, tất cả các đối tượng được lưu trữ trong bộ nhớ cache đều bị mất và vẫn tiếp tục tồn tại hoặc cập nhật trong cơ sở dữ liệu.
Bộ nhớ cache cấp hai (Second-level)
Bộ nhớ cache cấp hai là một bộ nhớ cache tùy chọn. Và bộ nhớ cache cấp một sẽ luôn được thảo luận trước khi thực hiện xác định vị trí một đối tượng trong bộ nhớ cache cấp hai. Bộ nhớ cache cấp hai có thể được cấu hình trên cơ sở mỗi lớp và mỗi collection và chịu trách nhiệm chính trong việc lưu trữ các đối tượng trong các session.
Bộ nhớ cache của bên thứ ba có thể được sử dụng với Hibernate. Một giao tiếp org.hibernate.cache.CacheProvider được cung cấp, phải được implements để cung cấp Hibernate với một xử lý để cài đăt bộ nhớ cache.
Bộ nhớ cache cấp truy vấn
Hibernate cũng thực hiện bộ nhớ cache cho các kết quả truy vấn kết hợp chặt chẽ với bộ nhớ cache cấp hai.
Đây là tính năng tùy chọn và yêu cầu thêm hai vùng bộ nhớ cache vật lý giữ kết quả truy vấn và các dấu thời gian khi một bảng được cập nhật lần cuối. Điều này chỉ hữu ích cho các truy vấn được chạy thường xuyên với các tham số giống nhau.
Sử dụng bộ nhớ cache trong Hibernate
Hibernate sử dụng bộ nhớ cache cấp một theo mặc định và bạn không phải làm gì để sử dụng bộ nhớ cache cấp một. Hãy đi thẳng đến bộ nhớ cache cấp hai tùy chọn.
Bộ nhớ cache cấp hai (Second-level)
Không phải tất cả các lớp đều được hưởng lợi từ bộ nhớ đệm, vì vậy điều quan trọng là có thể vô hiệu bộ nhớ cache cấp hai.
Bộ nhớ cache cấp hai Hibernate được thiết lập trong hai bước. Trước hết, bạn phải quyết định chiến lược truy cập đồng thời nào để sử dụng. Sau đó, bạn cấu hình hết hạn của bộ nhớ cache và thuộc tính bộ nhớ cache vật lý bằng cách sử dụng bộ nhớ cache provider.
Chiến lược truy cập đồng thời
Chiến lược truy cập đồng thời là bộ điều chỉnh có trách nhiệm lưu trữ các mục dữ liệu trong bộ nhớ cache và lấy chúng từ bộ nhớ cache. Nếu muốn kích hoạt bộ nhớ cache cấp hai, bạn sẽ phải quyết định, đối với mỗi lớp và collection persistent, mà chiến lược truy cập đồng thời vào bộ nhớ cache để sử dụng.
- Transactional: Sử dụng chiến lược này để đọc - chủ yếu là dữ liệu, nơi mà nó là quan trọng để ngăn ngừa dữ liệu cũ trong các transaction đồng thời, trong trường hợp hiếm hoi của một cập nhật.
- Read-write: Một lần nữa sử dụng chiến lược này để đọc - chủ yếu là dữ liệu, nơi nó là quan trọng để ngăn ngừa dữ liệu cũ trong các transaction đồng thời, trong trường hợp hiếm hoi của một cập nhật.
- Nonstrict-read-write: Chiến lược này không đảm bảo tính nhất quán giữa bộ nhớ cache và cơ sở dữ liệu. Sử dụng chiến lược này nếu dữ liệu hầu như không thay đổi và một khả năng nhỏ dữ liệu cũ không phải là mối quan tâm quan trọng.
- Read-only: Một chiến lược truy cập đồng thời phù hợp với dữ liệu mà không bao giờ thay đổi. Chỉ sử dụng nó cho dữ liệu tham khảo.
Nếu chúng ta sử dụng bộ nhớ đệm thứ hai cho lớp Employee. Hãy thêm phần tử mapping cần thiết để nói với Hibernate để cache các thể hiện Employee sử dụng chiến lược Read-only.
<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> <hibernate-mapping> <class name="Employee" table="EMPLOYEE"> <meta attribute="class-description"> Lớp này chứa chi tiết về employee. </meta> <!-- định nghĩa việc sử dụng bộ nhớ cache --> <cache usage="read-write"/> <id name="id" type="int" column="id"> <generator class="native"/> </id> <property name="firstName" column="first_name" type="string"/> <property name="lastName" column="last_name" type="string"/> <property name="salary" column="salary" type="int"/> </class> </hibernate-mapping>
Thuộc tính usage = "read-write" cho Hibernate sử dụng một chiến lược truy cập đồng thời đọc-ghi cho bộ nhớ cache được xác định.
Cache provider
Bước tiếp theo của bạn sau khi lựa chọn chiến lược đồng thời bạn sẽ sử dụng cho các lớp ứng cử viên bộ nhớ cache là việc chọn lựa một cache provider. Hibernate buộc bạn phải chọn một cache provider duy nhất cho toàn bộ ứng dụng.
No. | Cache Provider | Mô tả |
---|---|---|
1 | EHCache | Nó có thể cache trong bộ nhớ RAM hoặc trên đĩa cứng và clustered caching và nó hỗ trợ bộ nhớ cache kết quả truy vấn Hibernate tuỳ chọn. |
2 | OSCache | Hỗ trợ bộ nhớ đệm vào bộ nhớ RAM và đĩa cứng trong một JVM duy nhất, với một tập hợp đầy đủ các chính sách hết hạn và hỗ trợ bộ nhớ truy vấn. |
3 | warmCache | Một bộ nhớ cache cluster dựa trên JGroups. Nó sử dụng huỷ bỏ hiệu lực clustered nhưng không hỗ trợ bộ nhớ cache truy vấn Hibernate |
4 | JBoss Cache | Một bộ nhớ cache cluster được sao chép hoàn toàn hợp lệ được transaction dựa trên thư viện đa nhóm JGroups. Nó hỗ trợ nhân bản hoặc hủy bỏ hiệu lực, giao tiếp đồng bộ hoặc không đồng bộ, và khóa lạc quan và bi quan. Bộ nhớ truy vấn cache Hibernate được hỗ trợ |
Mỗi cache provider không tương thích với mọi chiến lược truy cập đồng thời. Ma trận tương thích sau sẽ giúp bạn chọn một sự kết hợp thích hợp.
Strategy/Provider | Read-only | Nonstrictread-write | Read-write | Transactional |
---|---|---|---|---|
EHCache | X | X | X | |
OSCache | X | X | X | |
SwarmCache | X | X | ||
JBoss Cache | X | X |
Bạn sẽ chỉ định cache provider trong file cấu hình hibernate.cfg.xml. Ví dụ sau, chúng ta chọn EHCache làm cache provider cấp hai:
<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE hibernate-configuration SYSTEM "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd"> <hibernate-configuration> <session-factory> <property name="hibernate.dialect"> org.hibernate.dialect.MySQLDialect </property> <property name="hibernate.connection.driver_class"> com.mysql.jdbc.Driver </property> <!-- thông tin kết nối db --> <property name="hibernate.connection.url"> jdbc:mysql://localhost/test </property> <property name="hibernate.connection.username"> root </property> <property name="hibernate.connection.password"> root123 </property> <!-- cài đặt cache provider --> <property name="hibernate.cache.provider_class"> org.hibernate.cache.EhCacheProvider </property> <!-- List các file XML mapping --> <mapping resource="Employee.hbm.xml"/> </session-factory> </hibernate-configuration>
Bây giờ, bạn cần chỉ định các thuộc tính của vùng nhớ cache. EHCache có file cấu hình riêng của mình, đó là ehcache.xml nên để trong CLASSPATH của ứng dụng. Cấu hình bộ nhớ cache trong ehcache.xml cho lớp Employee có thể như sau:
<diskStore path="java.io.tmpdir"/> <defaultCache maxElementsInMemory="1000" eternal="false" timeToIdleSeconds="120" timeToLiveSeconds="120" overflowToDisk="true" /> <cache name="Employee" maxElementsInMemory="500" eternal="true" timeToIdleSeconds="0" timeToLiveSeconds="0" overflowToDisk="false" />
Vậy là đủ, bây giờ chúng ta đã kích hoạt bộ nhớ cache cấp hai cho lớp Employee và Hibernate truy cập bộ nhớ cache cấp hai bất cứ khi nào bạn điều hướng tới Employee hoặc khi bạn tải Employee bằng mã nhận dạng.
Bạn nên phân tích tất cả các lớp và lựa chọn chiến lược bộ nhớ đệm thích hợp cho mỗi lớp. Đôi khi, bộ nhớ đệm cấp thứ hai có thể làm giảm hiệu suất của ứng dụng. Vì vậy, bạn nên chuẩn bị ứng dụng của mình trước mà không cần bật bộ nhớ đệm và sau đó cho phép bộ nhớ đệm phù hợp và kiểm tra hiệu suất. Nếu bộ nhớ đệm không cải thiện hiệu năng hệ thống thì không cần phải kích hoạt bất kỳ loại bộ nhớ đệm nào.
Bộ nhớ cache truy vấn
Để sử dụng bộ nhớ cache truy vấn, trước tiên bạn phải kích hoạt nó bằng cách sử dụng thuộc tính hibernate.cache.use_query_cache = "true" trong tệp tin cấu hình. Bằng cách thiết lập thuộc tính này thành true, bạn cho phép Hibernate tạo ra các bộ đệm cần thiết trong bộ nhớ để giữ các tập truy vấn và bộ nhận dạng (identifier).
Tiếp theo, để sử dụng bộ nhớ truy vấn, bạn sử dụng phương thức setCacheable(Boolean) của lớp Query. Ví dụ:
Session session = SessionFactory.openSession(); Query query = session.createQuery("FROM EMPLOYEE"); query.setCacheable(true); List users = query.list(); SessionFactory.closeSession();
Hibernate cũng hỗ trợ hỗ trợ bộ nhớ cache rất tinh vi thông qua khái niệm vùng nhớ cache. Một vùng nhớ cache là một phần của bộ nhớ cache được đặt tên.
Session session = SessionFactory.openSession(); Query query = session.createQuery("FROM EMPLOYEE"); query.setCacheable(true); query.setCacheRegion("employee"); List users = query.list(); SessionFactory.closeSession();
Đoạn code trên sử dụng phương thức để bảo Hibernate lưu trữ và tìm kiếm truy vấn trong vùng Employee của bộ nhớ cache.