先更新数据库再更新Redis为什么会出现脏数据?
来源:4-15 如何解决高并发场景下的缓存和数据库之间数据一致性问题

程序猿大叔文海
2023-08-28
数据库有行锁更新完之后事务没提交再更新Redis成功之后再提交事务,释放行数之后别的事务才能拿到行锁,请问你说的脏数据是哪一步有问题?
写回答
1回答
-
Danny_Idea
2023-08-28
嗯,这是个很好的问题,这里我们先假定场景是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,导致数据不一致。
所以我建议更合适的方案可以是在查询的时候再将数据刷入缓存中。
122024-06-10
相似问题