经常使用mybatis数据框架的朋友们想必对其中的缓存感到陌生吧,那么你是否还记得mybatis中的一级缓存和二级缓存呢?它们有什么区别呢?
一级缓存:其实就是Session级别的缓存。3132一个Session做了一个查询操作,它就会把这个操作的结果放在一级缓存里面。
如果说短时间内这个session(一定要是同一个session)又去做了同一个操作,那么hibernate会直接从一级缓存中拿,而不会再去连数据库去取数据了。因为它是内置的事务范围的缓存,不能被卸载的。
二级缓存:就是SessionFactory级别的缓存了。顾名思义就是查询的时候,会把查询结果缓存到二级缓存里边。
如果说同一个sessionFactory创建的某个session执行了相同的操作,那么hibernate就会从二级缓存中去拿结果,而不会再去连接数据库了。
这是可选的插件式的缓存呢,其实在默认情况下,SessionFactory是不会启用这个插件的。
我们可以在每个类或是每个集合的粒度上去配置的。缓存适配器用于去把具体的缓存实现与Hibernate集成的。
其实严格意义上说,SessionFactory缓存分为两类:即内置缓存和外置缓存。我们通常意义上说的二级缓存就是是指外置缓存。
内置缓存与session级别缓存实现方式很像。前者呢是SessionFactory对象的一些集合属性包含的数据,后者是指Session的一些集合属性包含的数据,SessionFactory的内置缓存中存放了映射元数据和预定义SQL语句。
映射元数据是映射文件中数据的拷贝;而预定义SQL语句是在Hibernate初始化阶段根据映射元数据推导出来的。
SessionFactory的内置缓存是只读的,应用程序不能修改缓存里面的映射元数据和预定义的SQL语句,所以SessionFactory不需要进行内置缓存跟映射文件的同步。
Hibernate的这两级缓存都位于持久化层,存放的都是数据库数据的拷贝。
缓存的两个特性如下:
1、缓存的范围:
它决定了缓存的生命周期以及可以被谁访问。缓存的范围分为三类。分别是:
事务范围
进程范围
集群范围
注意:其实对大多数应用来说,更慎重地考虑是否需要使用集群范围的缓存,因为访问的速度不一定会比直接访问数据库数据的速度快多少。
事务范围的缓存是持久化层的第一级缓存,通常来说它是必需的;进程范围或集群范围的缓存是持久化层的第二级缓存,一般来说是可选的。
2、缓存的并发访问策略:
当多个并发的事务同时访问持久化层的缓存的相同数据时,会引起并发问题,必须采用必要的事务隔离措施。在进程范围或者集群范围的缓存,即为第二级缓存,是会出现并发问题的。
因此呢可以设定以下四种类型的并发访问策略,以下每一种策略对应一种事务隔离的级别。
事务型并发访问策略是事务隔离级别最高的,只读型的隔离级别是最低的。就是说事务隔离级别越高,并发性能就越低。
事务型:仅仅在受管理环境中适用。它提供了Repeatable Read事务隔离级别。
对于经常被读但很少修改的数据,可以采用这种隔离类型,因为它可以防止脏读和不可重复读这类的并发问题。
读写型:提供了Read Committed事务得隔离级别。仅仅是在非集群的环境中适用的。
对于经常被读但很少修改的数据,可以采用这种隔离类型,因为它可以防止脏读这类的并发问题。
非严格读写型:不保证缓存与数据库中数据的一致性。就是说如果存在两个事务同时访问缓存中相同数据的可能,那么就必须为该数据配置一个很短的数据过期时间,从而尽量避免脏读。对于极少被修改,并且允许偶尔脏读的数据,可以采用这种并发访问策略。
只读型:对于从来不会修改的数据,如参考数据,是可以使用这种并发访问策略的。
好了,以上就是本篇文章的所有内容了,还想了解更多java常见问答知识,记得关注本站消息获取最新信息哦。
推荐阅读: