Hibernacja - buforowanie

Buforowanie to mechanizm zwiększający wydajność systemu. Jest to pamięć buforowa, która znajduje się między aplikacją a bazą danych. Pamięć podręczna przechowuje ostatnio używane elementy danych w celu jak największego zmniejszenia liczby trafień w bazie danych.

Buforowanie jest również ważne dla Hibernate. Wykorzystuje wielopoziomowy schemat buforowania, jak wyjaśniono poniżej -

Pamięć podręczna pierwszego poziomu

Pamięć podręczna pierwszego poziomu to pamięć podręczna sesji i jest to obowiązkowa pamięć podręczna, przez którą muszą przejść wszystkie żądania. Obiekt Session utrzymuje obiekt we własnym zakresie przed przekazaniem go do bazy danych.

Jeśli wydasz wiele aktualizacji obiektu, Hibernate próbuje opóźnić aktualizację tak długo, jak to możliwe, aby zmniejszyć liczbę wydawanych instrukcji SQL aktualizujących. Jeśli zamkniesz sesję, wszystkie buforowane obiekty zostaną utracone i zostaną utrwalone lub zaktualizowane w bazie danych.

Pamięć podręczna drugiego poziomu

Pamięć podręczna drugiego poziomu jest opcjonalną pamięcią podręczną, a pamięć podręczna pierwszego poziomu będzie zawsze sprawdzana przed podjęciem jakiejkolwiek próby zlokalizowania obiektu w pamięci podręcznej drugiego poziomu. Pamięć podręczna drugiego poziomu może być konfigurowana dla poszczególnych klas i kolekcji i jest głównie odpowiedzialna za buforowanie obiektów między sesjami.

W Hibernate można używać dowolnej pamięci podręcznej innej firmy. Naorg.hibernate.cache.CacheProvider interfejs, który należy zaimplementować, aby Hibernate miał dostęp do implementacji pamięci podręcznej.

Pamięć podręczna na poziomie zapytania

Hibernate implementuje również pamięć podręczną dla zestawów wyników zapytań, która jest ściśle zintegrowana z pamięcią podręczną drugiego poziomu.

Jest to funkcja opcjonalna i wymaga dwóch dodatkowych fizycznych regionów pamięci podręcznej, które przechowują buforowane wyniki zapytania i sygnatury czasowe ostatniej aktualizacji tabeli. Jest to przydatne tylko w przypadku zapytań, które są często uruchamiane z tymi samymi parametrami.

Pamięć podręczna drugiego poziomu

Hibernacja domyślnie używa pamięci podręcznej pierwszego poziomu i nie musisz nic robić, aby korzystać z pamięci podręcznej pierwszego poziomu. Przejdźmy od razu do opcjonalnej pamięci podręcznej drugiego poziomu. Nie wszystkie klasy korzystają z buforowania, dlatego ważne jest, aby móc wyłączyć pamięć podręczną drugiego poziomu.

Pamięć podręczna drugiego poziomu Hibernacji jest konfigurowana w dwóch krokach. Najpierw musisz zdecydować, której strategii współbieżności użyć. Następnie należy skonfigurować wygasanie pamięci podręcznej i atrybuty fizycznej pamięci podręcznej przy użyciu dostawcy pamięci podręcznej.

Strategie współbieżności

Strategia współbieżności to mediator, który jest odpowiedzialny za przechowywanie elementów danych w pamięci podręcznej i pobieranie ich z pamięci podręcznej. Jeśli zamierzasz włączyć pamięć podręczną drugiego poziomu, będziesz musiał zdecydować dla każdej trwałej klasy i kolekcji, której strategii współbieżności pamięci podręcznej użyć.

  • Transactional - Użyj tej strategii w przypadku danych głównie do odczytu, w przypadku których krytyczne jest zapobieganie przestarzałym danym w transakcjach współbieżnych, w rzadkich przypadkach aktualizacji.

  • Read-write - Ponownie użyj tej strategii dla danych głównie do odczytu, w przypadku których krytyczne jest zapobieganie przestarzałym danym w transakcjach współbieżnych, w rzadkich przypadkach aktualizacji.

  • Nonstrict-read-write- Ta strategia nie gwarantuje spójności między pamięcią podręczną a bazą danych. Skorzystaj z tej strategii, jeśli dane prawie nigdy się nie zmieniają, a małe prawdopodobieństwo nieaktualnych danych nie jest krytycznym problemem.

  • Read-only- Strategia współbieżności odpowiednia dla danych, które nigdy się nie zmieniają. Używaj go tylko do danych referencyjnych.

Jeśli zamierzamy używać buforowania drugiego poziomu dla naszego Employee dodajmy element mapujący wymagany do nakazania Hibernate buforowaniu instancji Employee przy użyciu strategii odczytu i zapisu.

<?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">
         This class contains the employee detail. 
      </meta>
      
      <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>

Atrybut use = "odczyt-zapis" mówi Hibernate, aby użył strategii współbieżności odczytu i zapisu dla zdefiniowanej pamięci podręcznej.

Dostawca pamięci podręcznej

Następnym krokiem po rozważeniu strategii współbieżności będzie użycie klas kandydatów do pamięci podręcznej, aby wybrać dostawcę pamięci podręcznej. Hibernate zmusza Cię do wybrania jednego dostawcy pamięci podręcznej dla całej aplikacji.

Sr.No. Nazwa i opis pamięci podręcznej
1

EHCache

Może buforować w pamięci lub na dysku i buforować klastrowo i obsługuje opcjonalną pamięć podręczną wyników zapytań Hibernate.

2

OSCache

Obsługuje buforowanie pamięci i dysku w pojedynczej maszynie JVM z bogatym zestawem zasad wygasania ważności i obsługą pamięci podręcznej zapytań.

3

warmCache

Pamięć podręczna klastra oparta na JGroups. Używa unieważniania klastrowego, ale nie obsługuje pamięci podręcznej zapytań Hibernate.

4

JBoss Cache

W pełni transakcyjna replikowana klastrowana pamięć podręczna również oparta na bibliotece multiemisji JGroups. Obsługuje replikację lub unieważnianie, synchroniczną lub asynchroniczną komunikację oraz optymistyczne i pesymistyczne blokowanie. Obsługiwana jest pamięć podręczna zapytań Hibernate.

Każdy dostawca pamięci podręcznej nie jest zgodny z każdą strategią współbieżności. Poniższa tabela zgodności pomoże Ci wybrać odpowiednią kombinację.

Strategia / dostawca Tylko czytać Nonstrictread-write Odczyt i zapis Transakcyjne
EHCache X X X  
OSCache X X X  
SwarmCache X X    
JBoss Cache X     X

Dostawcę pamięci podręcznej określisz w pliku konfiguracyjnym hibernate.cfg.xml. Wybieramy EHCache jako dostawcę pamięci podręcznej drugiego poziomu -

<?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>
   
      <!-- Assume students is the database name -->
   
      <property name = "hibernate.connection.url">
         jdbc:mysql://localhost/test
      </property>
   
      <property name = "hibernate.connection.username">
         root
      </property>
   
      <property name = "hibernate.connection.password">
         root123
      </property>
   
      <property name = "hibernate.cache.provider_class">
         org.hibernate.cache.EhCacheProvider
      </property>
   
      <!-- List of XML mapping files -->
      <mapping resource = "Employee.hbm.xml"/>
   
   </session-factory>
</hibernate-configuration>

Teraz musisz określić właściwości regionów pamięci podręcznej. EHCache ma własny plik konfiguracyjny,ehcache.xml, który powinien znajdować się w CLASSPATH aplikacji. Konfiguracja pamięci podręcznej w ehcache.xml dla klasy Employee może wyglądać następująco -

<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"
/>

To wszystko, teraz mamy włączone buforowanie drugiego poziomu dla klasy Pracownik i Hibernacja, teraz trafia do pamięci podręcznej drugiego poziomu za każdym razem, gdy nawigujesz do pracownika lub gdy ładujesz pracownika według identyfikatora.

Powinieneś przeanalizować wszystkie swoje klasy i wybrać odpowiednią strategię buforowania dla każdej z nich. Czasami buforowanie drugiego poziomu może obniżyć wydajność aplikacji. Dlatego zaleca się najpierw wykonać test porównawczy aplikacji, bez włączania buforowania, a później włączyć dobrze dopasowane buforowanie i sprawdzić wydajność. Jeśli buforowanie nie poprawia wydajności systemu, nie ma sensu włączać żadnego typu buforowania.

Pamięć podręczna na poziomie zapytania

Aby użyć pamięci podręcznej zapytań, musisz ją najpierw aktywować przy użyciu pliku hibernate.cache.use_query_cache="true"właściwość w pliku konfiguracyjnym. Ustawiając tę ​​właściwość na true, sprawisz, że Hibernate utworzy w pamięci niezbędne bufory do przechowywania zapytań i zestawów identyfikatorów.

Następnie, aby użyć pamięci podręcznej zapytań, należy użyć metody setCacheable (Boolean) klasy Query. Na przykład -

Session session = SessionFactory.openSession();
Query query = session.createQuery("FROM EMPLOYEE");
query.setCacheable(true);
List users = query.list();
SessionFactory.closeSession();

Hibernate obsługuje również bardzo precyzyjną obsługę pamięci podręcznej poprzez koncepcję regionu pamięci podręcznej. Region pamięci podręcznej jest częścią pamięci podręcznej, której nadano nazwę.

Session session = SessionFactory.openSession();
Query query = session.createQuery("FROM EMPLOYEE");
query.setCacheable(true);
query.setCacheRegion("employee");
List users = query.list();
SessionFactory.closeSession();

Ten kod używa metody, aby nakazać Hibernate przechowywanie i wyszukiwanie zapytania w obszarze pracownika pamięci podręcznej.