首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Hibernate 二級緩存深度實戰:EhCache 配置與最佳實踐

     編輯:Java 相關知識

二級緩存核心機制

Hibernate 二級緩存(L2 Cache)是 SessionFactory 級別 的緩存,跨會話共享。核心流程:

  1. ID 查詢(load()/get())優先檢查一級緩存 → 二級緩存 → 數據庫
  2. 查詢結果按 ID 存入二級緩存
  3. 增刪改操作同步更新緩存
  4. 僅對 ID 查詢生效,條件查詢需開啟查詢緩存

適合/不適合緩存的數據特徵

✅ 適合❌ 不適合
極少修改(字典、配置、參考數據)頻繁修改的業務數據
允許極短暫臟讀(非核心財務)絕對一致性要求(財務、庫存扣減)
非并發訪問或低并發多應用共享數據庫(外部修改不可感知)

EhCache 整合完整步驟

1. 依賴準備

  • ehcache-x.x.x.jar 放入 classpath
  • Hibernate 3.x: hibernate-ehcache.jar;4.x/5.x 已內置

2. Hibernate 配置啟用

<property name="hibernate.cache.provider_class">
    org.hibernate.cache.EhCacheProvider
</property>
<property name="hibernate.cache.use_second_level_cache">true</property>
<!-- 查詢緩存(可選) -->
<property name="hibernate.cache.use_query_cache">true</property>

3. 放置 ehcache.xml 到 src 根目錄

<ehcache>
    <diskStore path="java.io.tmpdir/ehcache"/>
    <defaultCache
        maxElementsInMemory="10000"
        eternal="false"
        timeToIdleSeconds="120"
        timeToLiveSeconds="120"
        overflowToDisk="true"
    />

    <!-- 實體緩存配置 -->
    <cache name="com.example.domain.Category"
        maxElementsInMemory="100"
        eternal="true"
        overflowToDisk="false"
    />

    <!-- 集合緩存配置(格式:實體全限定名.屬性名) -->
    <cache name="com.example.domain.Category.products"
        maxElementsInMemory="500"
        eternal="false"
        timeToIdleSeconds="300"
        timeToLiveSeconds="600"
        overflowToDisk="true"
    />

    <cache name="com.example.domain.Product"
        maxElementsInMemory="500"
        eternal="false"
        timeToIdleSeconds="300"
        timeToLiveSeconds="600"
        overflowToDisk="true"
    />
</ehcache>

4. 映射文件聲明緩存策略

<class name="Category" table="categories">
    <cache usage="read-write"/>  <!-- 實體緩存 -->
    <id name="id" .../>
    <version name="version" column="version"/> <!-- 必須有版本號支持樂觀鎖 -->
    ...
    <set name="products" table="products" cascade="all" inverse="true">
        <cache usage="read-write"/>  <!-- 集合緩存 -->
        <key column="categoryId"/>
        <one-to-many class="Product"/>
    </set>
</class>

<class name="Product" table="products">
    <cache usage="read-write"/>
    <id .../>
    <version name="version"/>
    ...
</class>

四大並發策略選型指南

策略適用場景事務隔離
read-only絕不修改(字典、配置)最快,無鎖
nonstrict-read-write極少修改,允許臟讀適度性能
read-write常規讀寫,需一致性軟鎖,性能較好
transactionalJTA 環境,強一致性完全事務性,開銷大

Spring 管理環境下的額外配置

<bean id="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
    <property name="hibernateProperties">
        <props>
            <prop key="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</prop>
            <prop key="hibernate.cache.use_second_level_cache">true</prop>
            <prop key="hibernate.cache.use_query_cache">true</prop>
        </props>
    </property>
</bean>

DAO 中啟用查詢緩存:

getHibernateTemplate().setCacheQueries(true);
List list = getHibernateTemplate().find("FROM Category");

關鍵注意事項

  • 版本號字段強制:實體必須有 <version> 支持樂觀鎖,否則并發更新會導致緩存不一致。
  • 集合緩存獨立配置:<set>/<bag> 需單獨聲明 <cache>,且關聯實體也需配置緩存才能緩存完整對象(否則只緩存 ID)。
  • 緩存同步陷阱:直接執行 HQL/SQL 批量更新(executeUpdate())不會自動失效二級緩存,需手動 sessionFactory.getCache().evictEntityRegion()。
  • 集群環境:單機 EhCache 不支持集群,需使用 Terracotta、Redis、Hazelcast 等分布式緩存實現。

總結

Hibernate 二級緩存能顯著降低數據庫壓力,但配置復雜、易踩坑。核心原則:只緩存「讀多寫少、允許最終一致」的數據,嚴格配置版本號與並發策略,集群環境必選分布式緩存方案。建議配合監控(如 EhCache MBeans)觀察命中率,持續優化。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved