采纳答案成功!
向帮助你的同学说点啥吧!感谢那些助人为乐的人
数据库有行锁更新完之后事务没提交再更新Redis成功之后再提交事务,释放行数之后别的事务才能拿到行锁,请问你说的脏数据是哪一步有问题?
嗯,这是个很好的问题,这里我们先假定场景是mysql的innodb存储引擎。
你所描述的场景 还比较特别,是在一个事务里面做了更新和redis的操作。如果update的sql有了事务的保护,自然是安全的,而且也必须要等到事务提交后,才能释放。但是通常来说,我们不会这么做,具体原因如下:
设计有点过度,没有涉及到多MySQL表的数据一致性保护,用事务的意义不大。
性能不高,通常引入了事务之后,写性能会降低很多倍
假设事务中的redis访问出现了网络超时,但是没有抛出异常,很可能会导致行锁或者表锁持有时间过久,需要考虑这类风险。
假设没有了事务的保护,那么我们来模拟下这种场景。
线程A:update了DB一条数据,写入Redis
线程B:update了线程A的同一条数据,写入Redis
顺序是线程A先更新完了DB,然后线程B再更新DB,那么DB的数据应该以线程B的为准。假设线程A在更新Redis的时候,因为一些网络问题,延迟了下,让线程B先刷入到了Redis中,然后过一段时间后,线程A的网络通畅了,把脏数据刷入了Redis,导致数据不一致。
所以我建议更合适的方案可以是在查询的时候再将数据刷入缓存中。
先更新数据库再删除缓存出现不一致的情况:查询事务先查询redis未命中,然后查询mysql命中,但还未更新到redis缓存,这个时候更新事务去数据库更新了该值,最后查询事务将旧值更新到redis。导致redis还是旧值,mysql是新值。这种情况存在吗?
存在 假设你的MySQL是主从架构,更新写到了master,此时数据还未同步到从节点 而又有请求路由到从节点进行数据查询,就会导致脏数据被带了出来。不过这种场景可以用缓存双删机制来避免。
登录后可查看更多问答,登录/注册
SpringCloudAlibaba高并发仿斗鱼直播平台实战
1.2k 16
568 9
420 7
413 7
170 7