Hibernate 脏数据检查机制与数据缓存

一. 脏数据检查机制

脏数据:   脏数据并非废弃或者无用的数据,而是指一个数据对象所携带的信息发生了改变之后的状态.

         如果我们从数据库中读取一个对象,事务提交时 Hibernate会对session 中的PO进行检测,判断哪些发生了变化,并将发生变化的数据更新到数据库中.

         Hibernate如何判断一个数据对象是否发生了改变,或者说 Hibernate 如何进行脏数据识别?

         脏数据检查的一般策略大致有下面两种:

         1.数据对象监控

                   数据对象监控的实现方式,大体上是通过拦截器对数据对象的设值方法 (setter) 进行拦截,拦截器的实现可以借助Dynamic Proxy 或者 CGlib 实现.一旦数据对象的设置方法被调用(通常这也就意味着数据对象的内容发生变化),则将其标志为"待更新"状态,之后在数据库操作时将其更新到数据库中.

         2.数据版本比对

                   在持久层框架中维持数据对象的最近读取版本,当数据提交时将提交数据与此版本进行比对,如果发生变化则将其同步到数据库中.

         Hibernate采取的是第二种检查策略

二. 数据缓存

         一般而言,ORM 的数据缓存应包含如下几个层次:

         1.事务级缓存

                   在当前事务范围内的数据缓存策略.

                   这里的事务可能是一个数据库事务,也可能是某个应用级事务.对于Hibernate而言,事务级缓存是基于Session 生命周期实现的,每个Session 会在内部维持一个数据缓存,此缓存随着Session 的创建(销毁)而存在(消亡),因此也称为Session Level Cache(也称为内部缓存)

         2.应用级/进程级缓存

                   在某个应用,或者应用中某个独立数据访问子集中的共享缓存.

                   此缓存可由多个事务(数据库事务或者应用级事务)共享.事务之间的缓存共享策略与应用的事务隔离机制密切相关.在Hibernate中,应用级缓存在SessionFactory层实现,所有由此SessionFactory 创建的Session 实例共享此缓存,因此也称为SessionFactory Level Cache.

                   多实例并发运行的环境(如多机负载均衡环境中),我们必须特别小心缓存机制可能带来的负面效应.

                   假设实例A 和实例B 共享同一数据库,并行运行,A和B各自维持自己的缓存,如果缺乏同步机制,A在某个操作中对数据库进行了更新,而B并没有获得相应的更新通知,其缓存中的数据还是数据库修改之前的版本,那行B在之后的读取操作中,可能就以此过期数据作为数据源,从而导致数据同步错误,这样的错误对于关键业务数据而言是无法承担的(如账务系统)

                   在这种情况下,应用级缓存无法使用,为了解决这个问题,我们引入了分布式缓存.

         3.分布式缓存

                   在多个应用实例,多个JVM之间共享的缓存模式.

                   分布式缓存由多个应用级缓存实例组成集群,通过某种远程机制(如RMI或JMS)实现各个缓存实例间的数据同步,任何一个实例的数据修改操作,将导致整个集群间的数据状态同步.

                   分布式缓存解决了多实例并发运行过程中的数据同步问题.

                   但是,除非对于并发读取性能要求较高,且读取操作在持久层操作中占绝大部分比重的情况,分布式缓存的实际效果尚需考证.

                   由于多个实例间的数据同步机制,每个缓存实例发生的变动都会复制到其余所有节点中(对于Repplication 式缓存而言),这样的远程同步开销不可忽视.

猜你喜欢

转载自blog.csdn.net/u013037661/article/details/51448614