Hibernate-Cache Management for Performance Optimization

Source: Internet
Author: User

1. cache Overview
 
Cache is a set of examples in memory in java applications. It stores backups of data from permanent storage sources (such as files or databases on hard disks, it reads and writes faster than hard disks. The application reads and writes data in the cache directly at runtime, and updates the data storage source synchronously only according to the data in the cache at certain times. If the volume of data stored in the cache is very large, the hard disk will also be used as the cached physical medium.
 
The purpose of caching is to reduce the frequency of applications directly reading and writing permanent data storage sources, thus enhancing the Running Performance of applications.
 
The implementation of cache not only needs to be used as the hardware (Memory) Of the physical media, but also needs to be used to manage the cache's concurrent access and expiration policies.
 
2. cache range Classification
 
The cache scope determines the cache declaration cycle and who can access the cache. Divided into three categories
 
1) Transaction Scope
 
 
The cache of the transaction scope can only be accessed by the current transaction. Each transaction has its own cache, and the data in the cache is usually in the form of correlated objects. the cache lifecycle depends on the transaction lifecycle. The cache lifecycle ends only when the transaction ends. the cache within the transaction scope uses the memory as the storage medium, and the first-level cache is within the transaction scope.
 
 
2) Application Scope (also called process scope)
 
 
The application cache can be accessed by all transactions within the application scope. the cache lifecycle depends on the application lifecycle. The cache lifecycle ends only when the application ends. the memory or hard disk can be used as the storage medium for application cache, and the second-level cache belongs to the application scope.
 
 
3) Cluster Scope
 
 
In the cluster environment, the cache is shared by processes of one or more machines, and the cached data is copied to each process node in the cluster environment, processes communicate remotely to ensure data consistency in the cache. Data in the cache is usually in the form of loose data of objects.
 
 
For most applications, you should carefully consider whether to use the cluster-range cache, because the access speed is not necessarily much faster than the direct access to database data.
 
 
3. cache concurrent access policies
 
When multiple concurrent errors access the same data cached in the persistence layer at the same time, the concurrency problem may occur. Necessary error isolation measures must be adopted.
 
The cache within the process scope or cluster scope may cause concurrency issues. Therefore, you can set four types of concurrent access policies, each of which corresponds to a transaction isolation level. Transaction-type concurrent access policies have the highest transaction isolation level and the lowest read-only isolation level. The higher the transaction isolation level, the lower the concurrency performance.
 
 
1) Transaction type: Applicable only to managed environments. It provides the Repeatable Read transaction isolation level. This isolation type can be used for data that is frequently read but rarely modified, because it can prevent concurrent problems such as dirty read and non-repeatable read.
 
 
2) Read/write type: Provides the Read Committed transaction isolation level. Applicable only in non-cluster environments. This isolation type can be used for data that is frequently read but rarely modified, because it can prevent concurrent problems such as dirty reads.
 
 
3) Non-strict read/write: The consistency between the cache and the data in the database is not guaranteed. If two transactions access the same data in the cache at the same time, you must configure a very short data expiration time for the data to avoid dirty reads. This concurrent access policy can be used for data that is rarely modified and occasionally dirty read.
 
 
4) read-only: This concurrent access policy can be used for data that has never been modified, such as reference data.
 
 
Cache in Hibernate
 
Hibernate provides two levels of cache. The first level is Session-level cache, which belongs to the transaction scope, and the second level is SessionFactory-level cache, it is a cache in or out of a range or within a cluster. This level of cache can be configured and changed, and can be dynamically loaded and detached. Hibernate also provides a query cache for query results, which relies on the second-level cache.
 
 
Level 1 Cache Management:
 
The first-level cache of Hibernate is provided by the Session, so it only exists in the Session lifecycle. When the program calls save (), update (), saveorupdate () when you call the query interface list, filter, or iterate, Hibernate adds the object to the first-level cache if the session cache does not contain the corresponding object,
When the Session is closed, the level-1 cache managed by the Session will be cleared immediately.
The Hibernate level-1 cache is built in the Session and cannot be uninstalled or configured.
 
The primary cache uses the key-value Map method. When the object is cached, the primary key ID of the object is the key of the Map, and the object is the corresponding value. Therefore, the level-1 cache is stored in Entity object units, and the primary keyword ID is used for access.
Although Hibernate uses automatic maintenance and does not provide any configuration functions for the level-1 cache, manual intervention can be performed on the management of the level-1 cache through the methods provided in the Session. The following two intervention methods are provided in Session:
● Evict (): Used to clear an object from the Session cache.
The evict () method is applicable to the following two situations:
1) No need to update the synchronized data of this object
2) during batch update and deletion, after each object is deleted, the memory occupied by this object must be released.
 
● Clear (): Used to clear all objects in the first-level cache. </P>
 
<P class = MsoNormal> when performing a one-time update of a large volume of data, it takes up a lot of memory to cache updated objects. In this case, the clear () method should be called periodically to clear the objects in the first-level cache and control the size of the first-level cache to avoid memory overflow.
How to handle cache when Hibernate is updated in batches:
(Assume that the age in our user table has 5000 records greater than 0 ,)
Session session = SessionFactory. openSession ();
Transaction tx = session. beginTransaction ();
Itertaor users = session. find ("from User u where u. age> 0"). itertaor (); // The HSL statement will not be explained.
While (user. hasNext ()){
User user = (User) users. next ();
User. setAge (user. getAge () + 1 );
// Write the inserted objects in this batch to the database immediately and release the memory.
Session. flush ();
Session. clear ();
}
Tx. commit ();
Session. close ();
When you use Hibernate to process a large number of data, you must first execute the 5000 update statement before updating the 5000 user objects ..
This affects the performance of the operation... when we encounter performance and space problems in the project, the performance should be the primary... this is to sacrifice space.
 
So it is better for the program to skip the Hibernate API and directly execute it through the jdbc api...
 
Let's change the above Code:
Session session = SessionFactory. openSession ();
Transaction tx = session. beginTransaction ();
Connection conn = session. connection ();
PreparedStatement pstmt = conn. prepareStatement ("update users set age = age + 1" + "where age> 0 ");
Pstmt.exe cuteUpdate ();
Tx. commit ();
Although this is done through the jdbc api, the boundary of the Transaction is declared through the interface of Hibernater Transaction in essence...
 
In fact, the best solution is to create a stored procedure and run it with the underlying database. This provides good performance and high speed ....
 
I will simply take the Oracle database as an example. Create a stored procedure named UserUpdate... and then call it in the program...
The Stored Procedure Code of UserUpdate:
Create or replace procadure UserUpdate (u_age in number)
Begin
Update users set age = age + 1 where age> u_age;
End;
The following describes how to call our named stored procedure in a program.
Session session = SessionFactory. openSession ();
Transaction tx = session. beginTransaction ();
Connection conn = session. connection ();
String str = "{call UserUpdate (?)} ";
CallableStatement cstmt = conn. prepareCall (str );
Cstmt. setInt (1, 0 );
Cstmt.exe cuteUpdate ();
Tx. commit (); Note: stored procedures are not supported in open-source MySQL ..
The advantage of using jdbc apis is that ..
It does not need to load a large amount of data into the memory in advance, and then update and modify it... so it will not consume a large amount of memory ....
(There is no difference in the small program .. when the data record reaches a certain amount of data, it will naturally find the difference between the Hibernate API and the jdbc api)
Only one record can be updated in batches. It is not like Updating each record in Hibernate ..
 
The first level is the Session cache. Because the lifecycle of a Session Object usually corresponds to a database transaction or an application transaction, its cache is the cache of the transaction scope. The first-level cache is required and cannot be detached. In the first cache, each instance of the persistence class has a unique OID.
 
 
 
Level 2 Cache Management
 

 
The second-level cache is a pluggable cache plug-in that is managed by SessionFactory. Because the life cycle of the SessionFactory object corresponds to the entire process of the application, the second-level cache is the cache of the Process scope or cluster scope. The loose data of the objects stored in the cache. The second-level object may have concurrency issues. Therefore, an appropriate concurrent access policy is required, which provides transaction isolation level for cached data. The cache adapter is used to integrate the specific cache implementation software with Hibernate. The second-level cache is optional. You can configure the second-level cache at the granularity of each class or set.
 
 
The general process of Hibernate's second-level cache policy is as follows:
 
 
1) When performing conditional queries, a select * from table_name where… is always issued .... (Select all fields) This SQL statement queries the database and obtains all data objects at a time.
 
 
2) put all the data objects obtained into the second-level cache by ID.
 
 
3) When Hibernate accesses the Data Object Based on the ID, it first looks up the data object from the Session level cache. If the Session level-2 cache is not found, it will be found from the level-2 cache, query the database and put the result into the cache by ID.
 
 
4) when data is deleted, updated, or added, the cache is also updated.
 
 
Hibernate's second-level cache policy is a cache policy for ID queries and does not work for conditional queries. Therefore, Hibernate provides a Query cache for conditional queries.
 
 
The process of Hibernate's Query cache policy is as follows:
 
 
1) Hibernate first sets a Query Key based on the information. The Query Key includes the general information of the request for conditional Query: The parameters required by SQL and the record range (starting position rowStart, maxRows.
 
 
2) Hibernate searches for the corresponding result list in the Query cache based on the Query Key. If yes, this result list is returned. If no, Query the database, obtain the result list, and put the entire result list into the Query cache based on the Query Key.
 
 
3) the SQL statement in the Query Key involves some table names. If any data of these tables is modified, deleted, or added, these related Query keys must be cleared from the cache.
 

 
 
There are four types of data that can be stored in the second-level cache:
 
1) rarely modified data
 
2) not very important data, allowing occasional Concurrent Data
 
3) data that will not be repeatedly asked
 
4) reference data refers to the constant data for reference supply. Its instance number is limited, and its instance will be referenced by many other classes. Its instances are rarely or never modified.
 
Data that is frequently modified, such as financial data (concurrent operations are definitely not allowed) and data shared by other applications, cannot be stored in the second-level cache.
 
 
Common cache plug-ins
 
Hibernate's second-level cache is a plug-in. Below are several common cache plug-ins
 
1) EhCache: it can be used as the cache for process access, and the storage physical medium can be memory or hard disk, which provides support for hibernate query cache.
 
2) OSCache: it can be used as a process-range cache. The physical medium for storing data can enable memory or hard disks. It provides a wide range of cache data expiration policies, and hibernate's query cache provides support.
 
3) SwarmCache: it can be used as a cache within the cluster, but does not support hibernate query cache.
 
4) TreeCache: it can be used as a cache within the cluster. It supports transactional concurrent access policies and provides support for hibernate query cache.
 
 
Second-level cache example
 
Configuration 1:
 

 
Added to the hibernate. cfg. xml file.
 
Java code collection code
 
<Span style = "font-size: large;"> <! -- Enable Level 2 Cache -->
<Property name = "cache. provider_class"> org. hibernate. cache. EhCacheProvider </property>
<! -- Enable query cache -->
<Property name = "hibernate. cache. use_query_cache"> true </property> </span>
 

 
Configuration 2:
 
Create an ehcache. xml file under the src file of the Project. Its content is
 
Java code collection code
 
<Span style = "font-size: large;"> <? Xml version = "1.0" encoding = "UTF-8"?>
<Ehcache>
<DiskStore path = "java. io. tmpdir"/>
<DefaultCache maxElementsInMemory = "10000" eternal = "false" overflowToDisk = "true" timeToIdleSeconds = "300" timeToLiveSeconds = "180" diskPersistent = "false" timeout = "120"/>

</Ehcache> </span>
 
Configuration 3:
 
To cache certain objects, you must add the <cache usage = "read-only"/> attribute to the hbm file, for example:
 
Add Xml code to favorites
 
<Span style = "font-size: large;"> <? Xml version = "1.0"?>
<! DOCTYPE hibernate-mapping PUBLIC "-// Hibernate/Hibernate Mapping DTD 3.0 // EN"
Http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd>
<! --
Mapping file autogenerated by MyEclipse-Hibernate Tools
-->
<Hibernate-mapping>

<Class name = "com. vogue. bbsphoto. entity. Forum"
Table = "cdb_forums">
<Cache usage = "read-only"/>
<Id name = "ID" column = "fid" unsaved-value = "null">
<Generator class = "increment"/>
</Id>

<Property name = "name" column = "name" type = "string"/>
<Property name = "type" column = "type" type = "string"/>
</Class>
</Hibernate-mapping>
</Span>
 
Configuration 4:
 
To use the Query cache, The cacheable must be set to true and query. setCacheable (true );
 
For example, the method used for hql query in the dao parent class is modified:
 
Java code collection code
 
<Span style = "font-size: large;"> /**
* Query of hql statements

* @ Param SQL
* @ Return
*/
Public List executeQuery (String hql ){
List list = new ArrayList ();
Session session = HibernateSessionFactory. currentSession ();
Transaction tx = null;
Query query = session. createQuery (hql );
Query. setCacheable (true );
Try {
Tx = session. beginTransaction ();
List = query. list ();
Tx. commit ();
} Catch (Exception ex ){
Ex. printStackTrace ();
HibernateSessionFactory. rollbackTransaction (tx );

} Finally {

HibernateSessionFactory. closeSession ();
}
Return list;
}
</Span>
 
Note: When the object to be cached is in a cascading relationship. If the object that has a cascading relationship with it has the property <cache usage = "read-only"/>, after the first get operation, all objects in the object graph of the object will be saved to the second-level cache of hibernate. When the second get operation is performed on this object, find all cascading objects directly from the level-2 cache. If a cascading object does not have the <cache usage = "read-only"/> attribute, it will not be saved to the second-level cache, and will still execute SQL to find the cascade object in the database every time you get

Author: ERDP Technical Architecture"

Related Article

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.