IT修真院·小课堂丨互联网职业小课堂在线学习平台

课堂课题:

什么是脏数据,缓存中是否可能产生脏数据,如果出现脏数据该怎么处理?

关联任务:

任务五

直播时间:

2018-12-01 18:30:00


课堂内容:

视频链接:

PPT链接:

提交按钮:

小课堂内容格式


标题:

【修真院xx(职业)小课堂】课题名称

开场语:

大家好,我是IT修真院XX分院第X期的学员XX,一枚正直纯洁善良的XX程序员,今天给大家分享一下,修真院官网XX(职业)任务X,深度思考中的知识点——XXX

(1)背景介绍:

背景介绍的时候,尽可能的要宽广,讲清楚来龙去脉,讲清楚为什么会需要这个技术。

(2)知识剖析:

讲知识点的时候,尽可能的成体系,学会成体系的去给别人介绍知识。现在很多做的都是零散的,没有分类。

(3)常见问题:

最少列出1个常见问题。

(4)解决方案:

写清楚常见问题的解决方案。

(5)编码实战:

尽可能的去寻找在真实项目中在用的。如果你能找到某个网站在用你说的知识点,这是最好的。学以致用,否则当成练习题就没有意义了。多准备一些demo,讲解过程中将知识点和demo结合,便于大家理解所讲解的知识点。

(6)拓展思考:

知识点之外的拓展思考,由分享人进行讲解,这些东西就是所谓的深度,也是一个人技术水准高低比较的表现。

(7)参考文献:

引入参加文献的时候,在引用的句子后面加上序号【1】。参考文献中列出详细来源。不要去抄别人的东西,这是一个基本的态度。

(8)更多讨论:

Q1:提问人:问题?
A1:回答人(可以是分享人,也可以是其他学员):回答
Q2:提问人:问题?
A2:回答人(可以是分享人,也可以是其他学员):回答
Q3:提问人:问题?
A3:回答人(可以是分享人,也可以是其他学员):回答

(9)鸣谢:

感谢XX、XX师兄,此教程是在他们之前技术分享的基础上完善而成。

(10)结束语:

今天的分享就到这里啦,欢迎大家点赞、转发、留言、拍砖~

什么是脏数据,缓存中是否可能产生脏数据,如果出现脏数据该怎么处理?     中品

辅导师兄


标题:

【修真院java(职业)小课堂】课题名称

开场语:

大家好,我是IT修真院上海分院第10期的学员许东杰,一枚正直纯洁善良的java程序员,今天给大家分享一下,修真院官网java(职业)任务六,深度思考中的知识点——

什么是脏数据,缓存中是否可能产生脏数据,如果出现脏数据该怎么处理?

(1)背景介绍:


脏数据:从目标中取出的数据已经过期、错误或者没有意义,这种数据就叫做脏数据。

脏读:读取出来脏数据就叫脏读。


(2)知识剖析:

1、数据库中的并发事务处理问题:

脏读:在并发访问的情况下,不同的事务对相同的数据进行操作,在事务A修改数据还未提交的时候,事务B对该数据进行读取,读出了事物A修改过后的数据,但是事物A最终没有提交,这种情况就是数据库中的脏读情况

更新丢失:对于同一行数据不同事务进行更新,结果覆盖

幻读:事务A前后两次读取,后一次读取的数据变多了,事物B在两次读取中间已经进行数据插入

不可重复读:事务A读取了事务B修改前后的两次数据,不符合隔离型

隔离等级:可以解决上述问题,mysql默认可重复读的隔离等级,只会存在读取的数据和数据库不一致的问题

2、mybati一级缓存中的脏数据:

mybatis的一级缓存:默认是SqlSession级别,只要通过session查过的数据,都会放在session上,下一次再查询相同id的数据,都直接冲缓存中取出来,而不用到数据库里去取了。

mybatis一级缓存脏数据:当有不同的sqlSession在对数据库进行操作,一级缓存只能保证当前sqlSession中的增删改在一级缓存中自动更新,就会产生脏数据。

3、mybati二级缓存中的脏数据:

mybatis二级缓存:是SessionFactory级别,和namespace绑定,同一个namespace放到一个缓存对象中,当这个namaspace中执行了非sselect语句的时候,整个namespace中的缓存全部清除掉。


mybatis二级缓存脏数据:引起脏读的操作通常发生在多表关联操作中,比如在两个不同的mapper中都涉及到同一个表的增删改查操作,当其中一个mapper对这张表进行查询操作,此时另一个mapper进行了更新操作刷新缓存,然后第一个mapper又查询了一次,那么这次查询出的数据是脏数据。出现脏读的原因是他们的操作的缓存并不是同一个。


所以不推荐使用mybatis的自带一二级缓存,推荐使用第三方缓存:memcached或者redis。


(3)常见问题:

redis中怎么更新缓存避免脏读?

(4)解决方案:

读写部分:

if(redis存在数据){

    读取redis数据

}else{

    数据库读取,同时存redis+设置超时时间


更新部分:

if(数据库update){

    更新redis+设置超时时间


(5)编码实战:

演示读写部分和更新部分

(6)拓展思考:

还有哪些其他方式进行redis数据更新

1、主动更新:后台点击更新缓存按钮,从DB查找最新数据集合,删除原缓存数据,存储新数据到缓存(或者用定时任务来做)

问题:更新过程中删除掉缓存后刚好有业务在查询,那么这个时候返回的数据会是空,会影响用户体验,如果高并发穿透DB,可能导致服务器崩溃

2、由用户触发更新:前台获取数据时发现没有缓存数据就会去数据库同步数据到缓存

问题:当并发请求获取缓存数据不存在的时候,就会产生并发的查询数据的操作

3、提前加载好数据:后台点击更新缓存按钮,从DB查找最新数据集合,这里不删除缓存,通过遍历数据覆盖和删除掉无效的数据

问题:逻辑相对麻烦,而且更新机制无法通用


(7)参考文献:

百度谷歌

(8)更多讨论:

Q1:数据库脏数据和redis脏数据的区别?

A1:数据库脏数据是用户对数据进行操作存储,存储的数据和实际不符合,redis脏数据是相对于数据库数据而言的,redis的数据和数据库中数据不一致就会导致脏数据
Q2:文中代码实战中的redis更新方式有什么缺点?

A2:缺点:增加的判断的方法,效率偏低,当并发量高时,效率影响会更大
Q3:主动更新方式进行redis更新怎么实现?
A3:在后台管理中,设置一个按钮,更新redis的操作,一般在晚上用户访问量少的时候,数据从数据库中查出后放入redis

(9)鸣谢:

感谢朱明星师兄,此教程是在他们之前技术分享的基础上完善而成。

(10)结束语:

今天的分享就到这里啦,欢迎大家点赞、转发、留言、拍砖~


评论

[上海|荣耀师兄]JAVA-朱明星 发表于 2018-12-04 14:47:24 #1

关于数据最应该解决的就是失效策略, 我给你老大的原话,你也想一想,什么时候缓存应该过期,延着这个思路走下去,再去想,能否不用业务开发人员去控制缓存的读写,而是全部交给一个中间件来去做?

回复

请您登录 后进行评论