因为项目中经常出现,由于使用了hibernate生成的方法,会从二级缓存中拿取数据,导致数据不一致的问题,甚至导致出现脏数据的问题,所以总结以下hibernate的缓存机制。

什么是二级缓存

我们知道一级缓存,并且一级缓存的作用范围就在session中,每个session都有一个自己的一级缓存,而二级缓存也就是比一级缓存的作用范围更广,存储的内容更多,我们知道session是由sesssionFactory创建出来的,一个sessionFactory能够创建很多个session,每个session有自己的缓存,称为一级缓存,而sessionFactory也有自己的缓存,存放的内容供所有session共享,也就是二级缓存。

 一级缓存:保存session中,事务范围的缓存(通俗点讲,就是session关闭后,该缓存就没了,其缓存只能在session的事务开启和结束之间使用)

 二级缓存:保存在SessionFactory,进程范围内的缓存(进程包括了多个线程,也就是我们上面说的意思,A线程可能拿到一个session进行操作,B线程也可能拿到一个session进行操作,但是A和B读能访问到SessionFactory中的缓存,也就是二级缓存,这里只是拿A,B说事,可能有一个线程刚创建出来session,也能拿到二级缓存中的数据)

hql做的查询能够存入一级缓存和二级缓存,但是不能够从二级缓存中拿数据

get\load能够将其查询数据插入一级缓存和二级缓存,也能够从一级二级缓存中拿数据。

例如:

我们有一个Order对象,是一个实体对象,对应数据库中order表中的一条记录,经过查询已有n个Order对象被放入二级缓存中。现在我们要修改order表中任意任x条记录,执行以下HQL:

template.bulkUpdate("update Order set owner = ? where id in (?,?,?)");

这时Hibernate会直接将二级缓存中的n个Order对象清除掉。 天啊,居然不是你想像的修改谁就同步更新二级缓存中的谁,而是清除了二级缓存中全部的Order类型的对象。为什么?这一切是为了保证“数据一致性”。你执行了HQL修改了order表中的x条记录,这x条是哪几条?如果sql是子查询:update Order set owner =? where id in(select id from *** ),谁知道你修改了order表中的哪几条记录,你自己都不知道,Hibernate更不知道了。所以为了保证二级缓存中的数据与order表中的数据一致,只能清除了二级缓存中全部的Order类型的对象。二级缓存频繁的载入与清除,这样缓存命中率就会下降。

二级缓存的更新机制

 存放了对于查询结果相关的表进行插入,更新,删除操作的时间戳,Hibernate通过时间戳缓存区域来判断被缓存的查询结果是否过期,如果过期了则从数据库中拿数据,没过期则直接从缓存中拿数据。通俗点讲,就三步

1、查询结果放到二级缓存中,此时记录一个时间为T1

2、当有操作直接更改了数据库的数据时,比如使用hql语句,就会直接对数据库进行修改,而不会改变缓存中的数据。此时记录时间为T2

3、当下次在查询记录时,会先将T1和T2进行比较,如果T2>T1,则说明缓存中的数据不是最新的,那么就从数据库中拿出正确的数据,如果T2<T1,就说明没有对数据库进行过什么修改操作,那么就可以直接从缓存中获取数据。

解惑:如果没有T1和T2的比较,那么会出现我们查询到的数据不是准确的,因为就像上面第二步所说的,数据库的数据会和缓存中的数据不一样,什么都不做就从缓存中拿数据,就会出现错误。

这里需要注意:如果你用了update语句,那么二级缓存无法更新。因为系统无法判断二级缓存的对象哪些失效了。如果你是update(对象)的方式更新,则系统可以通过ID确认哪个二级缓存对象需要更新,系统能够维护二级缓存。

项目中出现的缓存问题分析

由于项目的beta和prod环境是有多台server集群的,所以如果在某些对数据一致性要求较高的地方使用了二级缓存(也就是从缓存中取数据,不是直接从db中查取数据),就会出现数据一致性问题。

原因:由于server的elb机制是粘性session,那么就可能出现用户A和admin连上了两台不同的server,并且所有的db操作都是在不同的server上进行的,这时候如果admin更新的用户A的状态信息,只会刷新admin所连接server的二级缓存,并不会刷新其他server的缓存,而用户A并不能及时获取到db的更新,如果所有的地方都是从二级缓存中取数据就还好,只会出现延时的问题,这种可能性比较小。但如果不是全部都从二级缓存中取数据,那用户A就会出现数据不一致问题,甚至导致页面挂掉。

上面这种情况当清楚的db的catch之后就可以恢复正常,但还有一种更严重的情况,如果用户A从缓存中获取的和db不一致的数据,并做的相应的更新操作,那么就会直接导致数据库出现脏数据,直接导致这个用户出现问题。

所以hibernate需要慎用,在更新较为频繁或者对数据一致性较高的地方不要使用二级缓存,否则会得不偿失。

Hibernate二级缓存相关推荐

  1. Hibernate二级缓存的使用

    1启用Hibernate二级缓存 Hibernate二级缓存分为两部分,class缓存和查询缓存,其获取对象的方式有所不同,但两者也有联系,查询缓存必须以class缓存为基础才能起作用,否则只会使效率 ...

  2. Hibernate 二级缓存使用

    1启用Hibernate二级缓存 Hibernate二级缓存分为两部分,class缓存和查询缓存,其获取对象的方式有所不同,但两者也有联系,查询缓存必须以class缓存为基础才能起作用,否则只会使效率 ...

  3. Hibernate EHCache - Hibernate二级缓存

    Hibernate EHCache - Hibernate二级缓存 欢迎使用Hibernate二级缓存示例教程.今天我们将研究Hibernate EHCache,它是最受欢迎的Hibernate二级缓 ...

  4. 配置Hibernate二级缓存步骤

    配置Hibernate二级缓存步骤: 加入二级缓存的jar包及配置文件 jar包位置:hibernate-release-4.1.8.Final\lib\optional\ehcache下所有jar包 ...

  5. Hibernate二级缓存问题

    相关概念和定义 1.缓存的意义 把一些不常修改,但是又经常用的数据存放到内存中,这样能减少与数据库的交互,提升程序的性能 2.Hibernate中提供了两级缓存: 第一级别的缓存是Session级别的 ...

  6. HibernateEHCache –Hibernate二级缓存

    Welcome to the Hibernate Second Level Cache Example Tutorial. Today we will look into Hibernate EHCa ...

  7. hibernate二级缓存(三) 自定义实现一个简单的hibernate二级缓存

    hibernate二级缓存(三) 自定义实现一个简单的hibernate二级缓存 前面我们已经提及过hibernate内部为二级缓存的扩展做了很多的实现.我们只需要实现RegionFactoryTem ...

  8. spring boot 2.1.4 hibernate二级缓存 Hazelcast实现(一)

    Hazelcast优势网上都可以查到,默认的分布式缓存,使用Hazelcast替换ehcache优势比较明显,也方便项目从单机到发展分布式,而不用再引入其他组件也达到了性能要求,按照springboo ...

  9. Hibernate二级缓存详解(转)

    Hibernate二级缓存详解(转) 本文转载 http://www.blogjava.net/supercrsky/articles/238580.html 与Session相对的是,Session ...

  10. ssh整合hibernate 使用spring管理hibernate二级缓存,配置hibernate4.0以上二级缓存

    ssh整合hibernate 使用spring管理hibernate二级缓存,配置hibernate4.0以上二级缓存 hibernate  : Hibernate是一个持久层框架,经常访问物理数据库 ...

最新文章

  1. CodeGen准备存储库
  2. 从“小”培养AI安全意识:OpenAI开源具有安全约束的RL训练工具
  3. GNU make manual 翻译( 一百一十九)
  4. win10+VS2013+opencv2.4.11的安装和配置
  5. 基于jquery的一个javascript前端框架实现
  6. HBA driver for linux
  7. 机器学习篇-指标:AUC
  8. oracle mssql 实例,oracle,mysql,SqlServer三种数据库的分页查询的实例
  9. Linux入门学习(四)
  10. SOTIF - 汽车感知系统验证和确认
  11. css3 中background的新增加的属性的用法(一)
  12. 世上最杰出程序员,B 语言、Unix 之父为玩游戏,写了个操作系统
  13. 【Python】【jupyter-notebook】
  14. webservice wsdl 生成服务
  15. copying mysql status_MySQL主从复制延迟原因及处理思路
  16. 【.NET开发之美】使用ComponentOne提高.NET DataMap中的加载速度
  17. 如何用html实现文件下载
  18. 免费下载的音乐的6个网站,非常实用!
  19. Unity3D引擎各大插件免费下载地址
  20. --go_out: protoc-gen-go: plugins are not supported问题处理

热门文章

  1. 再见,罗永浩!再见,锤子!
  2. windows上修改docker镜像保存地址
  3. PowerDesiger导出简洁数据字典
  4. SI9000学习笔记
  5. AMEsim柱塞泵的建模学习
  6. python-数据结构-大学生-航空订票系统
  7. 飞机大战(Java)
  8. sony android 计算器,NeoCal 全能计算器 V2.0.2
  9. 系分 - 企业信息化战略与实施
  10. 微信小程序直播为什么这么受欢迎