数据缓存---持久层性能提升的关键。
缓存:是数据库数据在内存中的临时容器,它包含了库表数据在内存中的临时拷贝,位于数据库与数据访问层之间。
ORM数据读取:首选缓存,查到则返回,避免了数据库调用的性能开销。
对于企业级应用,数据库与应用服务器位于不同的物理服务器,也就是每次数据库访问都是一次远程调用--Socket的创建于销毁,数据的打拆包,数据库执行查询指令,网络传输的延时等。
(1) 数据缓存策略
ORM的数据缓存应包含:
a、事务级缓存(事务范围内):基于Session生命周期。
b、应用级/进程级缓存(在SessionFactory层实现),所有由此SessionFactory创建的Session实例共享此缓存。但在多实例并发运行会产生问题:A,B共享同一数据库,各自维持其缓存,A对数据库进行了更新,B缓存数据仍为更新前。
c、分布式缓存(在所个应用实例,多个JVM之间共享的缓存模式),由多个应用级缓存实例组成集群。---解决了多实例并发运行过程中的数据同步问题。
注意:如果当前应用于其它应用共享数据库,采取一些保守策略(避免缓存机制的使用)可能更加稳妥。
(2) Hibernate数据缓存
a、内部缓存(Session Level)
b、二级缓存(SessionFactory Level)
Hibernate缓存发挥作用的情况:
a、通过id(主键)加载数据时 ---Session.load(),Session.iterate()
b、延迟加载
内部缓存:应用事务级缓存,由Hibernate自动维护,可通过以下方法手动干预。
Session.evict---将某个特定对象从内存缓存中清除。
Session.clear---清空内部缓存。
二级缓存:涵盖了应用级缓存和分布式缓存。
Session在进行数据查询操作时,会首先在自身内部的一级缓存中进行查找,如果一级缓存未能命中,则在二级缓存中查询,如果二级缓存命中,则以此数据作为结果返回。
引入二级缓存需要考虑的问题:
(1),数据库是否与其它应用共享
(2),应用是否需要部署在集群环境中
满足以下条件,则可将其纳入缓存管理
(1),数据不会被第三方应用修改
(2),数据大小载客接受的范围之内
(3),数据更新频率较低
(4),同一数据可能会被系统频繁使用
(5),非关键数据(关键数据,如金融账户数据)
(3) 第三方缓存实现
(1),JCS--某些情况下可能导致内存泄漏以及死锁。
(2),EHCache--默认---无法做到分布式缓存。
(3),OSCache
(4),JBoss Cache--提供分布式缓存(Repplication方式)
(5),SwarmCache--提供分布式缓存(invalidation方式)
Hibernate中启用二级缓存,需配置hibernate.cfg.xml如下:
<hibernate-configutarion> <session-factory> ...... <property name="hibernate.cache.provider_class"> net.sf.ehcache.hibernate.Provider <property> ...... </session-factory> <hibernate-configuration> 还需要配置ehcache.xml。 之后,需要在我们的映射文件中指定各个映射实体(以及collection)的缓存同步策略: <class name="TUser"> <cache usage="read-write"/> ... <set name="addresses" ...> <cache usage="read-write"/> ... </set> </class>
(4) 缓存同步策略
--为了使得缓存调度遵循正确的应用级事务隔离机制,必须为每个实体类指定相应的缓存同步策略。
4种内置的缓存同步策略:read-only,nonstrict-read-write,read-write,transactional(JTA,此时的缓存类似一个内存数据库)