Hibernate cache application accumulation and summary, and hibernate cache Accumulation

Source: Internet
Author: User

Hibernate cache application accumulation and summary, and hibernate cache Accumulation

Hibernate cache has been relatively difficult to grasp, the following analysis and summary of the reasons, I believe you will gradually understand the original Hibernate cache can also be easily mastered, however, the premise is that you must verify it with your hands and try again. It is useless to look at it.

Directory:

1. hibernate first-level cache (Session-level cache)

Ii. Primary cache features and applications

Iii. Manage Level-1 Cache

Iv. Hibernate second-level cache (sessionFactory-level cache)

V. Summary

1. hibernate first-level cache (Session-level cache) 

Hibernate is a thread that corresponds to a session. A thread can be considered as a user. That is to say, the session-level cache (level-1 cache) can only be used by one thread, and other threads cannot use it. level-1 cache is bound to the thread. The life cycle of the hibernate first-level cache is very short. Like the session life cycle, the first-level cache is also called the session-level cache or the transaction-level cache. If the tb transaction is committed or rolled back, the session is closed and the lifecycle ends.

  Experiment 1: experience level-1 Caching: (do it manually)

// In the same session, issue two load methods to query the Employee emp = (Employee) session. load (Employee. class, 1); System. out. println (emp. getName (); // No query statement is issued. load uses the cache emp = (Employee) session. load (Employee. class, 1); System. out. println (emp. getName ());

The second query of the same data for the first time, the second load method is to retrieve data from the cache, without sending an SQL statement to the database for query.

Cache is mainly used for query. Many methods of hibernate are to retrieve data from the cache first. If the data is not obtained from the database, the query efficiency can be improved, such as get ()/load (), iterate (), and persistent objects are stored in the cache. For example, if you save the object and use the load method to query the object you just saved, the load method does not issue an SQL statement to query the object in the database, but instead retrieves data in the cache, because the save method also supports caching.

Ii. Primary cache features and applications:

  1. Session-level cache, which is consistent with session state.Its lifecycle is the same as that of the session. The Session is destroyed, and it is also destroyed;

  2. Two sessions cannot share a level-1 cache.Because it will be accompanied by the creation and destruction of the session lifecycle;

  3. Session cache is an entity-level cache.It is used only at the query object level. If HQL and SQL are used at the query attribute level, level 1 cache is not used! Remember !!!

  4. Use cache for iterate queries, The SQL and HQL statements for querying the Id will be issued, but the object query will not be issued. After the query is complete, the corresponding entities will be placed in the cache. If some object queries are cached, it is queried from the cache, but the SQL and HQL statements of the query id will still be issued. If it is not in the cache, it will be queried in the database, and then the queried entities will be put in the cache one by one, so there will be N + 1 problems.

  5. Differences between List () and iterate queries: (do it manually)

Use iterate and list to query the object * N + 1. By default, query. iterate can be used to query the object * N + 1.

The so-called N + 1 is to issue N + 1 SQL statement 1 during the query: first, issue the sqlN of the query object id list:

Query by id list to the cache. If no matched data exists in the cache, what is the difference between the corresponding SQL statement list and iterate Based on the id?

List issues an SQL statement each time. list puts data into the cache instead of using the data in the cache.

Iterate: by default, iterate uses cached data. However, if no data exists in the cache, the problem of N + 1 may occur.

 6. Get () and load ()The iterate method uses a level-1 cache,

What is the difference between Get and load? (Manual)

1. for the get method, hibernate checks whether the data corresponding to this id exists. First, it searches in the session cache and then in the second-level cache. If no data exists, it queries the database, if the database does not exist, null is returned.

2. When loading an object using the load method, the following situations are discussed based on the configuration of the Class-level lazy attribute in the ing file (the default value is true:

(1) If the value is true, first query the Session cache to check whether the object corresponding to this id exists. If the object does not exist, use delayed loading, returns the proxy object of an object (this proxy class is a subclass of the object class, which is dynamically generated by CGLIB ). When this object is used (except for obtaining OID), the second-level cache and database will be queried. If no matching record is found, an ObjectNotFoundException will be thrown.

(2) If the value is false, the query sequence is the same as that of the get method. However, if no matching record is found, an ObjectNotFoundException will be thrown.

Summary:

1. The get method first queries the session cache. If there is no session cache, It queries the second-level cache and the database. The load method first queries the session cache and creates a proxy if there is no session cache, the second-level cache and database are queried only when data is actually used.

2. If no matching record is found, the get method returns null, and the load method throws an ObjectNotFoundException.

3. load uses the proxy to delay data loading, while the get method often returns objects with Entity Data

Usage:

1. If you want to add, delete, modify, and query an object, use the load Method to Improve the Performance. You can use a proxy object to save a chance to interact with the database, interaction with the database only when the attribute of this object is actually used

2. If you want to load an object and use its attributes, use the get method.

  7. The Stored Procedure of hiberate3 session is as follows:

For example, the object Session. save (object );

At this time, data will not be stored in the database, and will be first stored in the session cache. The database does not have the corresponding records, and session. flush (); will be used to issue SQL and HQL statements. The database has corresponding records,

However, the database cannot be found using the select statement, which is related to the transaction level of the database.

Session. beginTrransaction (). Commit ();

After the transaction is submitted, You can query it.

Session. flush () statement but why not write it, Because commit () will call flush () by default ();

Iii. Manage Level-1 Cache

Whenever you pass an object to the save (), update (), or saveOrUpdate () method, or use load (), get (), list (), iterate () or the scroll () method to obtain an object, the object will be added to the internal cache of the Session. When the flush () method is subsequently called, the object state is synchronized with the database. If you do not want this synchronization operation to happen, or you are processing a large number of objects and need to manage the memory effectively, you can call the evict () method, remove these objects and their collections from the first-level cache.

ScrollableResult cats = sess.createQuery("from Cat as cat").scroll();while ( cats.next() ) {    Cat cat = (Cat) cats.get(0);    doSomethingWithACat(cat);    sess.evict(cat);}

Session also provides a contains () method to determine whether an instance is in the cache of the current session. To completely clear all objects from the session cache, you need to call Session. clear ().

Iv. Hibernate second-level cache (sessionFactory-level cache)

The second-level cache needs to be managed by sessionFactory. It is a primary cache and can be used by all users. It is shared. Hibernate second-level cache supports object cache, set cache, and query result set cache. Optional for query result set cache.

The second-level cache is complex and generally used by third-party products. Hibernate provides a simple implementation. Hashtable can only be used for testing. Third-party products are required for commercial use.

  Several excellent cache solutions:

  1. Memcached distributed CACHE system 2, jboss cache 3, and EhCache Ehcache 2.1 provide JTA support for Hibernate. 4. Infinispan open-source data grid platform

Using the cache is definitely a data that remains unchanged for a long time. It doesn't make much sense if the changed data is put into the cache. Because of frequent changes, you still need to query in the database frequently, so there is no need to use the cache. Hibernate has made some optimizations and is integrated with some third-party cache products. The EHCache cache product is used here.

Integration with the EHCache second-level cache product: the jar file of EHCache is in the lib of hibernate. We also need to set a series of Cache Usage policies. We need a configuration file ehcache. xml for configuration.

  Hibernate. cfg. xml configuration (manual) 

<! -- Enable Level 2 cache --> <property name = "hibernate. cache. use_second_level_cache"> true </property> <! -- Enable query cache --> <property name = "hibernate. cache. use_query_cache"> true </property> <! -- Prefix of the second-level cache region name --> <! -- <Property name = "hibernate. cache. region_prefix"> h3test </property> --> <! -- High-speed cache provider third-party product --> <property name = "hibernate. cache. region. factory_class"> net. sf. ehcache. hibernate. EhCacheRegionFactory </property> <! -- Specify the cache configuration file location --> <property name = "hibernate. cache. provider_configuration_file_resource_path"> ehcache. xml </property> <! -- Force Hibernate to store data in the second-level cache in a more user-friendly format --> <property name = "hibernate. cache. use_structured_entries"> true </property> <! -- Hibernate Collects performance-tuning statistics --> <property name = "hibernate. generate_statistics"> true </property>

Ehcache configuration (ehcache. xml) (manual)

<? Xml version = "1.0" encoding = "UTF-8"?> <Ehcache name = "h3test"> <! -- Specify the region name --> <defaultCache maxElementsInMemory = "100" <! -- Maximum number of cached files in memory --> eternal = "false" <! -- Whether the cache is persistent --> timeToIdleSeconds = "1200" <! -- Destroy a cache entry after being idle for n seconds --> timeToLiveSeconds = "1200" <! -- Destroys a cache entry after it is alive for n seconds --> overflowToDisk = "false"> <! -- Hard disk overflow --> </defaultCache> </ehcache>

Entity read-only Cache

Read-only cache read-only, no locks and transactions are required, because the cache will not change after data is loaded from the database. If the data is read-only, such as referencing data, the "read-only" policy is always used because it is the simplest and most efficient policy and also a cluster security policy. The top performance strategy

Second-level cache test code (manual)

Session session1 = sf. openSession (); Transaction t1 = session1.beginTransaction (); // ensure that the database has Voucher voucher = (Vocher) session1.get (Vocher. class, 1); // if it is modified, an error is returned. the read-only cache cannot be modified. // voucher. setName ("aaa"); t1.commit (); session1.close (); Session session2 = sf. openSession (); Transaction t2 = session2.beginTransaction (); voucher = (Vocher) session2.get (Vocher. class, 1); // search results in the second-level cache. SQL statements are not generated, and database t2.commit (); session2.close (); sf. close ();

The read-only cache cannot be updated. The error "Can't write to a readonly object" is returned. Add allowed (add directly to Level 2 cache)

Read/write Cache

Cache updates occur after database transactions are completed. The cache must support locks. Update the database in a transaction. After the transaction is completed successfully, update the cache and release the lock. A lock is only a specific expression of invalid cache values. It blocks other transactions from reading and writing the cache before it obtains the new database value. Those transactions will directly read the database.

Entity read/Write Cache

Second-level cache test code

Session session1 = sf. openSession (); Transaction t1 = session1.beginTransaction (); // ensure that the database has Voucher voucher = (Vocher) session1.get (Vocher. class, 1); // if it is modified, an error is returned. the read-only cache cannot modify voucher. setName ("aaa"); t1.commit (); session1.close (); Session session2 = sf. openSession (); Transaction t2 = session2.beginTransaction (); voucher = (Vocher) session2.get (Vocher. class, 1); // This entry has been modified by another transaction. At this time, the database t2.commit (); session2.close (); sf. close ();

Update is allowed. The update is automatically synchronized to the cache. New records can be added and automatically synchronized to the cache. Ensure that the read committed isolation level and Repeatable read isolation level (implemented by timestamp) Lock the entire process. If the timestamp of the current transaction is earlier than the timestamp of the entry in the second-level cache, this indicates that the entry has been modified by another transaction. At this time, the database is re-queried. Otherwise, the cached data is used. Therefore, the Repeatable read isolation level is ensured.

  Nonstrict read/write Cache

Update the database in a transaction and clear the cache before the transaction is completed. For the sake of security, the cache is cleared again after the transaction is completed, regardless of whether the transaction is successful or not. You do not need to support cache locks or transactions. In a cache cluster, the "Clear cache" call will invalidate all copies. This is often called the "pull" update policy. If your data reads a lot or has few concurrent cache accesses and updates, you can use the "nonstrict-read-write" policy. Thanks to its lightweight "pull" update policy, which is usually the second best performance policy.

Entity non-strict read/write Cache

Test Code omitted (I think you will verify it)

  Verification Result

Update is allowed. The cache becomes invalid after the update. You need to query it again. New records can be added. New records are automatically added to the second-level cache. The entire process is not locked and is not guaranteed.

  Transaction cache transactional (must be in the JTA environment)

Updates to the cache and database are encapsulated in the same JTA transaction, so that the cache and database are always synchronized. Both the database and cache must support JTA. Unless you really want to put cache updates and database updates in a JTA transaction, do not use the "transactional" policy because JTA requires a long two-phase commit process, as a result, it is basically the worst-performing strategy.

Support for specific caches and JTA transactions is required, which is not demonstrated here.

Set Cache

Demo read/write cache example, similar to the previous object cache test, other self-testing

SessionFactory sf = new Configuration (). configure (). buildSessionFactory (); Session session1 = sf. openSession (); Transaction t1 = session1.beginTransaction (); // make sure that the database has UserModel user = (UserModel) session1.get (UserModel. class, 1); user. getVouchers (); t1.commit (); session1.close (); Session session2 = sf. openSession (); Transaction t2 = session2.beginTransaction (); user = (UserModel) session2.get (UserModel. class, 1); user. getVouchers (); t2.commit (); session2.close (); sf. close ();

  Test conclusion:

This policy has the same meaning as the entity concurrency policy. However, the set cache only caches the identifier of the Set element, and only stores the identifier of the corresponding entity in the second-level cache, then, the identifier is used to go to the second-level cache and the final combination of the corresponding entities is returned as a set.

Query cache (manual)

1. Make sure that the query cache is enabled in the global configuration.

2. Modify FarmModel. hbm. xml and add the following red configuration to indicate the object cache and read/write.

3. Test code

SessionFactory sf =. new Configuration (). configure (). buildSessionFactory (); Session session1 = sf. openSession (); Transaction t1 = session1.beginTransaction (); Query query = session1.createQuery ("fromVoucher"); // a query is required even if the Query cache is enabled globally. setCacheable (true); List <Voucher> voucherList = query. list (); t1.commit (); session1.close (); Session session2 = sf. openSession (); Transaction t2 = session2.beginTransaction (); query = session2.createQuery ("from Voucher"); // a query is required even if the query cache is enabled globally. setCacheable (true); voucherList = query. list (); t2.commit (); session2.close (); sf. close ();

  Conclusion:

It has the same meaning as the entity concurrency policy. Similar to the set cache, only the identifier of the Set element is cached, and only the identifier of the corresponding entity is stored in the second-level cache, then, the identifier is used to go to the second-level cache and the final combination of the corresponding entities is returned as a set.

When do I need to query the cache?

In most cases, you cannot benefit from the result set cache. You must know how often the same query is repeated. For applications with a large number of queries but few inserts, deletes, and updates, the query cache can improve performance. However, it is useless to write multiple queries, and it is always invalid.

Manage Level 2 Cache

For the second-level cache, many methods are defined in SessionFactory to clear cache instances, classes, collection instances, or the entire set.

SessionFactory. evict (Cat. class, catId); // evict a special CatsessionFactory. evict (Cat. class); // evict all CatssessionFactory. evictCollection ("Cat. kittens ", catId); // evict a special collection of kittenssessionFactory. evictCollection ("Cat. kittens "); // evict all kitten collectionssessionFactory. the evictQueries () // evict all queries // CacheMode parameter is used to control how a specific Session interacts with the second-level cache. // CacheMode. NORMAL-reads and writes data from the second-level cache. // CacheMode. GET-reads data from the second-level cache, and writes data to the second-level cache only when the data is updated. // CacheMode. PUT-only writes data to the second-level cache, but does not read data from the second-level cache. // CacheMode. REFRESH-only writes data to the second-level cache, but does not read data from the second-level cache. Use the settings of hibernate. cache. use_minimal_puts to force the second-level cache to read data from the database and refresh the cache content.

  Monitoring Level 2 Cache

To view the content of the second-level cache or query the cache area, you can use the Statistics API. Use sessionFactory. getStatistics (); To obtain Hibernate statistics. In this case, you must manually enable the statistics option.

 hibernate.generate_statistics true hibernate.cache.use_structured_entries true
V. Summary

Don't take it for granted that the cache will certainly improve performance. This is the case only when you can control it and the conditions are appropriate. There are still many restrictions on the second-level cache of hibernate, And the inconvenience of using jdbc may greatly reduce the update performance. 1 + N problems may occur if you do not understand the principle. Improper use may also lead to dirty Data Reading.

If you can't stand hibernate's many restrictions, You Should cache your own applications.

The higher the cache, the better the effect. It seems that even if the disk has a cache, the database still needs to implement its own cache. Even if the database has a cache, our applications still need to be cached. Because the underlying cache does not know what the top layer will do with the data, it can only do more common, while the top layer can implement the cache in a targeted manner, so it can cache at a higher level, the effect is also better.

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.