Hibernate caching Principle and strategy

Source: Internet
Author: User
Tags emit sessions

Hibernate caching Principle :

Caching is especially important for an ORM such as Hibernate, which is the key to the performance improvement of the persistence layer. In short, hibernate is the encapsulation of JDBC to achieve internal state management, or mapping, etc., but the resulting data access efficiency is reduced, and the performance of the decline , and caching is an important way to compensate for this shortcoming.

A cache is a temporary container for database data in memory, including a temporary copy of the database data in memory, which is located between the database and the database access layer. ORM queries the data first according to its own cache management policy, in the cache to find relevant data, such as the discovery of the required data, then directly use this data as a result, so as to avoid the cost of database call performance. In contrast to memory operations, database invocation is a costly process.
In general, the cache in ORM is divided into the following categories:
1:transaction-level caching: A data cache that is within the scope of the current transaction. In terms of Hibernate, transaction-level caching is based on the life cycle of the session, and there is a data cache within each session, which exists as the session is created and dies as the session is destroyed. therefore also known as session level Cache.
2:application-Level caching: That is, in an app or in an application where a standalone database accesses a shared cache in a sub-set, this cache can be shared by multiple transactions (database transaction or application transaction), and the cache sharing policy between transactions is closely related to the transaction isolation mechanism applied. In Hibernate, The application-level cache is implemented by Sessionfactory, and all session instances created by a sessionfactory share this cache, and therefore are also known as sessionfactory levels cache.
3:Distributed Cache: A cache policy that is shared among multiple JVMs across multiple instances of the application. Distributed cache is composed of multiple application-level cache instances, and the data synchronization between each cache instance is realized through some remote mechanism (RMI,JMS), and the data modification of any one instance will result in synchronization of the data state between the whole cluster.

Hibernate one, level two cache policy:

Hibernate provides a level two cache, and the first level of cache is session-level caching, which is a transaction-scoped cache. This level of caching is managed by Hibernate, and generally does not require intervention; the second level of caching is the cache at the sessionfactory level, which is a process-wide or cluster-wide cache. This level of caching can be configured and changed, and can be dynamically loaded and unloaded, belonging to a multi-transaction level, to prevent transactional concurrency.

The cache is stored in map form (key-id,value-object)

First level cache (Session):

Transaction scope, each transaction (Session) has a separate first-level cache.

First-level cache management: When the application invokes the session's Save (), update (), Saveorupdate (), get (), or load (), and the list (), iterate () that invokes the query interface (using the N+1 query, check the ID first) or the filter () method, Hibernate adds the object to the first level cache if the corresponding object does not exist in the session cache. When you clean up the cache, hibernate synchronizes updates to the database based on the state of the objects in the cache. Session provides two ways for the application to manage the cache: evict (object obj): Clears the persisted object specified by the parameter from the cache. Clear (): Empties all persisted objects in the cache, flush (): Synchronizes the cache with the database.

Caching is not supported when querying the corresponding word Geru (name) instead of the object.

Second-level cache (Sessionfactory):

The general process for Hibernate's level two cache strategy is as follows:

1: When a condition is queried, always issue a SELECT * FROM table_name where .... (select all fields) such SQL sentence query database, one time to get all the data objects (this problem to consider, if you query 100,000 data, memory is not occupied).

2: Put all the obtained data objects into the second level cache based on the ID.

3: When hibernate accesses the data object according to the ID, it is first checked from the session cache, and if the level two cache is configured, it is checked from the level two cache, the database is not found, and the results are placed in the cache by ID.

4: Update the cache while deleting, updating, and adding data.

Hibernate's level two cache policy, which is a cache policy for ID queries, has no effect on conditional queries. To do this, Hibernate provides query Cachefor conditional queries.

Concept explanation

There are two caching mechanisms available in Hibernate: First-level cache, two-level cache, because the two-level cache policy is a cache policy for ID queries, and for conditional queries, Hibernate provides query cache for conditional queries.

一、一级 Cache:

The first-level cache is hibernate, independent of user intervention, its life cycle and session life cycle consistent, the current session once closed, the primary cache will disappear, therefore, the primary cache is also called session cache or transaction-level cache, first-class cache only Store entity objects , the general object properties are not cached , that is, when the object is obtained, the object is cached, if it is in the same session to get the object, it will first determine if there is no ID of this object in the cache, if any, it is directly removed from the cache, otherwise, to access the database, This object is cached when it is taken.

二、二级 Cache:

The second level cache is also called the process cache or the Sessionfactory cache, it can be shared by all sessions, the life cycle of the level two cache is consistent with the lifetime of the Sessionfactory, and the level two cache also stores only entity objects .

The general process for a secondary cache is as follows:

①: Gets the entity object that is queried when the condition is queried

②: Put all of the obtained data objects into the level two cache based on the ID

③: When hibernate accesses the data object according to the ID, first from the Sesison cache, if the configuration of level two cache, will be found from the level two cache, if you do not find, then query the database, the results by ID into the cache

④: The cache is updated while the delete, update, add operation is in progress

Third, query cache:

The query cache is a cache of the normal attribute result set, only the ID is cached for the result set of the entity object, and for frequently used query statements, if query caching is enabled, hibernate will store the query results in a level two cache when the query is executed for the first time, and when the query statement is executed again later, Simply get query results from the cache, which improves query performance, stored in the query cache as key-value pairs, and The key key is the query's conditional statement (the specific key rule should be: class name + Method Name + parameter list), value for the result set to wait for after the query. ID list .

The general process for querying the cache is as follows:

①:query Cache Saves the selectsql that the query executed before, and the result set, and so on, form a query Key

②: When the query request is encountered again, will be based on Querykey from the Querycache, found on the return, but when the data table data changes, Hbiernate will automatically clear the corresponding query Key Querycache

We can see from the policy of query cache that the query cache works only under certain conditions and is very demanding:

①: Exactly the same selectsql repeated execution

②: Querykey Corresponding data table cannot have data changes during repeat execution

Caching-enabled configuration

Configure query cache and level two cache in EJB

1. Enable caching in Persistence.xml
<persistence-unitname= "gxpt-qx-entity" transaction-type= "JTA" ><!--for performance testing of JPA--><provider> Net.bull.javamelody.jpapersistence</provider> <jta-data-source>java:/mysqlds</jta-data-sou                                  Rce> <!--<jta-data-source>java:/MyOracleDS</jta-data-source>-- <properties> <!--<propertyname= "Hibernate.dialect" value= "Org.hiberna Te.dialect.Oracle10gDialect "/>-<propertyname=" Hibernate.dialect "value=" org.hibernate . dialect. Mysqldialect "/><propertyname=" Hibernate.hbm2ddl.auto "value=" Update "/><propertyname=" Hibernate.show _sql "value=" true "/> <!--specify provider for level two cache products--><propertyname=" Hibernate.cache.provider_class "value=" Net.sf.ehcache.hibernate.SingletonEhCacheProvider "/><!--<propertyname=" hibernate.cache.re Gion.factory_class "Value=" Org.hibernate.cache.ehcache. Ehcacheregionfactory "/>--><!--turn on level two cache--><propertyname=" Hibernate.cache.use_second_level_cache " Value= "true"/><!--open Query cache--><propertyname= "Hibernate.cache.use_query_cache" value= "true"/> <!-- Specify cache configuration file location--><propertyname= "Hibernate.cache.provider_configuration_file_resource_path" value= "/ Ehcache.xml "/> </properties></persistence-unit>
2. Use annotations to specify that the user class uses level two caching
@Entity @table (name= "Tq_user") @Cache (usage=cacheconcurrencystrategy.nonstrict_read_write) publicclass user
3, open the query cache, in addition to the above configuration in the Persistence.xml, but also need to manually open the query cache in the underlying code

Query.sethint ("Org.hibernate.cacheable", true);

or query.setcacheable (true);

Performance tests through SQL statements

1, two cache off, query cache open and close comparison * * * * * * * Normal property query

Public String Mycache () {        list<string>-strings = This.userserviceimpl                . Search ("Selectu.username from User u where id<4 ORDER by ID ASC ");        for (String str:strings) {           System.out.println ("Username:" + str);        }         System.out.println ("===================================");        List<string> strings2 =this.userserviceimpl                . Search ("Select U.usernamefrom User u where id<4 ORDER by ID ASC ");        for (String str:strings2) {           System.out.println ("Username:" + str);        }        return "/mycache";    }

The current level two cache is turned off to see the query results when the query cache is closed:

  Public list<string> Search (stringhql) {        list<string> rtnstrs = newarraylist<string> ();        try {           Session session = This.sessionFactory.openSession ();            Session.begintransaction ();            Query query = session.createquery (HQL);            Query.setcacheable (TRUE);//Manually turn on query cache            rtnstrs = (list<string>) query.list ();            Session.gettransaction (). commit ();        } catch (Exception e) {            System.out.println ("DAO layer fails query based on HQL statement");        }        return rtnstrs;    }

Query.setcacheable (True) is masked in the above code.

Close the level two cache and close the query cache run as follows:

Turn on query caching, turn off level two cache to run as follows

Conclusion: For querying the normal properties, regardless of whether the level two cache is on or not, as long as the query cache is turned on, when the SQL statement executed two times is the same, the second time does not issue the SQL statement, directly from memory.

2. When the query cache is turned on, the level two cache turns on and off compare ******* query entity object

/**     * Query cache on, level two cache off ******* query entity object     *     Run Result: If the query cache and level two cache are turned off, SQL statements are issued at two queries, and two query statements     *     * Running result: If the query cache is turned on, the level two cache is turned off, and the second time an N-query statement that queries the entity by ID is issued     *     Run Conclusion: The first time the list is executed, the ID of the query object is cached in the query cache. The second time the list is executed (two times the same as the query SQL statement), will traverse the ID in the query cache to the     * (Level Two) cache to find the entity object, when not, then issue a query to the database query     * */        publicstring Mycache3 () {list<user>users1 = This.userServiceImpl.search ();           for (User u:users1) {              System.out.println ("users1:username:" + u.getusername ());          }   System.out.println ("===============");         List<user> users2 =this.userserviceimpl.search ();        for (User u:users2) {           System.out.println ("users2:usersname:" + u.getusername ());        } return "/mycache";    }

Turn on the query cache and turn off the level two cache to run as follows: (two times the SQL is emitted and the second N statement is issued)

Turn on query caching, turn off level two cache to run as follows (only one statement is issued)

Summarize:

(1), when only using Hibernate to query the cache, while closing the level two cache:

① If the query is a partial attribute result set, then the second query will not emit a SQL statement, directly from the Hibernate query cache to fetch data

② If the query is an entity result set (Eg.from User) This hql, then the queried entity, first hibernate query cache holds the entity ID, the second query, the Hibernate query cache to take out the ID of a one to the database query, This will emit n SQL statements, causing SQL flooding. Therefore, when using the query cache, it is best to cooperate with the level two cache.

(2), when opening Hibernate query cache and level two cache:

① If you are querying a partial attribute result set, this is the same as when you close the level two cache with only the Hbiernate query cache, because no entities are involved and the level two cache is not used.

② If the query is an entity result set, then the queried entity first holds the ID of the entity in the query cache, and the entity object is saved to the level two cache, the second query, the Hibernate query cache to take the ID, according to the ID to go to the level two cache matching data, If there is data, the SQL statement will not be issued, if any, the second query a SQL statement will not be issued, directly from the level two cache to fetch data.

by Javamelody

Javamelody can monitor Java or Java EE application servers in a running environment. It is displayed as a graph: Java memory and Java CPU usage, number of user sessions, JDBC connections, and HTTP requests, SQL requests, JSP pages and Business interface methods (EJB3, Spring, Guice), average execution time, Error percentage, and so on.

Quintiq Blog has introduced Java project performance monitoring and tuning tools-javamelody

Monitor Item Cache Count

This is the cache in the right entry for this development, in total 12, where the red ones are level two cache and query cache, respectively

Monitoring of the Spring

Add Cache condition

No cache conditions

Based on statistical results, it is found that caching can actually improve performance.

However, sometimes using the cache instead of performance degradation, such as the Update method, because the data changes, hibernate needs to keep the cache and the database two copies of the data synchronization, so after the cache, update performance is reduced, add, delete operation is the same reason.

So the cache is suitable for situations where there are a large number of queries in the project, otherwise it is not necessary to apply.

Q: What data is suitable for storage in the second level cache?

1. Data that is rarely modified

2. Data that is not very important, allowing occasional concurrent data to occur

3. Data that will not be accessed concurrently

4. Reference data, refers to the supply of constant data reference, its limited number of instances, its instances will be referenced by many other instances of the class, the instance is rarely or never modified.

Not suitable for storing data in a second level cache?

1 frequently modified data

2 financial data, never allow concurrency

3 data that is shared with other apps.

The usual cache plug-in Hibernater's level two cache is a plug-in, and here are a few common cache plugins:

EhCache: As a process-wide cache, the physical media that holds the data can be either memory or hard disk, which provides support for Hibernate's query caching.

Oscache: As a process-wide cache, the physical media that holds the data can be either memory or hard disk, providing a rich cache data expiration policy that supports Hibernate's query caching.

Swarmcache: Can be used as a cluster-wide cache but does not support Hibernate's query cache.

JBossCache: Can be used as a cluster-wide cache, supports transactional concurrency access policies, and provides support for hibernate query caching.

Primary steps for configuring level two caching:

1 Select the persistent class that requires a level two cache, and set its concurrent access policy for the named cache. This is the most serious step to consider.

2 Select the appropriate cache plug-in, and then edit the plugin's configuration file.

Hibernate caching Principle and strategy

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.