其实对于缓存而言,它其实就是一块内存空间,在这个空间中存放了相互关联的持久化对象, 也就是存在于Session缓存内的对象,那么Session负责根据持久化对象的状态变化来同步的更新数据库。

  Session的缓存是内置的不可卸载的,我们也称其为一级缓存,除了一级缓存,SessionFactory有一个内置的缓存和一个外置的缓存,其中外置的缓存是可插拔的缓存插件,也被称为Hibernate的二级缓存。

二.缓存的作用:

     缓存的作用是减低应用程序直接读写永久性数据存储源的频率,从而提供应用的运行性能。

三.缓存的实现原理

     缓存它是介于应用程序和永久性数据存储源之间,那么我们常见的永久性数据存储源有硬盘上的文件还有数据等,其实我们可以把缓存中的数据理解成是数据存储用中数据的拷贝,应用程序在运行时直接读写缓存中的数据,只在某些特定的时刻按照缓存中的数据来同步更新数据存储源。

  缓存在软件系统中的位置图解:

四.持久化层缓存的范围

       持久化层的缓存的范围决定了缓存的生命周期以及可以被谁访问。缓存的范围可以分为三类:事务范围,进程范围,群集范围。

1.事务范围:

            我们通常说的一级缓存,它就是一个事务范围的一个缓存,就是当事务提交了,或者事务回滚等操作,都是结束了一个事务,那么我们在开启另一个事务的时候,想在去获取缓存中的数据时,这时是获取不到的。所以说缓存的生命周期依赖于事务的生命周期,当一个事务结束了,缓存的生命周期也就结束了,那么我们在这里可以总结出每个事务都有自己独自的缓存。

      事务范围的缓存存储:

  在同一个事务的缓存中,持久化类的每个对象具有唯一的OID(相当于数据库中表的主键,我们都知道主键是唯一的),所以相同的OID不可能出现两次,那么我们还是以Emp(员工)和Dept(部门)为例来看一下事务范围的缓存存储:

           

2.进程范围的缓存:

     缓存可以被进程内的所有事务共享。进程范围的缓存可能会存放大量数据,它的物理介质可以是内存或硬盘。缓存内的数据及可以采用相互关联的对象形式,也可以采用对象的散装数据形式:

 01.进程范围的缓存存放相互关联的对象:

    

       上图的数据存放形式,数据库中OID为1的Dept对象在内存中始终只有一个拷贝。这种数据存放形式的优点是节省内存。但是我们要考虑在并发环境中,当执行不同事务的各个线程同时长时间操纵同一个OID为1的Dept对象时,必须对这些线程进行同步,而同步会影响并发性能,并且很容易导致死锁(两个事务都要提交的场景),所以在进程范围内部不建议使用这种数据存放机制。

    

 02.进程范围的缓存存储散装数据:

   如果缓存中的数据采用的对象时散装数据形式,那么当不同的事务到缓存中查询OID为Dept对象时,获取的Dept对象的散装数据,每个事务都必须分别根据散装数据重新构造出Dept实例,也就是说,每个事务都会获取不同的Dept对象。

3.群集范围:

     在群集环境中,缓存被同一个机器或多个机器上的多个进程共享。缓存中的数据被复制到群集的环境中的每个进程节点,进程之间通过远程通信来保证缓存中数据的一致性,缓存中的数据通常是采用对象的散装数据形式。

        对于大多数应用,应该慎重的考虑是否需要使用群集范围的缓存,有时它未必能提高应用性能,应为访问群集范围的缓存的速度不一定会比直接访问数据库的速度快多少。

五.缓存的查询机制

      

      持久化层可以提供多种范围的缓存。如果在事务范围的缓存中没有查询到相应的数据,还可以到进程范围或群集范围的缓存中查询,如果在进程范围或群集范围的缓存内没有找到数据,那么只能查询数据库。事务范围的缓存是持久化层的一级缓存,它是必需要走的,进程范围或群集范围的缓存是持久化层的第二级缓存,它是可选的。