Loading [MathJax]/jax/output/CommonHTML/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >redis与mysql的数据一致性问题(并发更新)

redis与mysql的数据一致性问题(并发更新)

作者头像
GeekLiHua
发布于 2025-01-21 05:19:47
发布于 2025-01-21 05:19:47
10100
代码可运行
举报
文章被收录于专栏:JavaJava
运行总次数:0
代码可运行

redis与mysql的数据一致性问题(并发更新)

并发更新引发的问题

案例场景: 考虑一个在线购物系统,其中商品库存信息存储在MySQL数据库中,同时使用Redis缓存了商品库存以提高读取速度。多个用户同时购买同一商品,导致MySQL和Redis同时发生库存更新操作。

问题: 在这种情况下,可能会发生竞争条件,导致MySQL和Redis中的库存数量不一致。例如,两个用户同时查询库存,得到相同的库存数量,然后都尝试购买,最终导致超卖或者库存数量错误。

解决方案

使用锁机制: 通过在关键操作中使用锁,可以确保在同一时刻只有一个线程可以执行该操作,避免了竞争条件。在Redis中,可以使用WATCHMULTI命令实现乐观锁。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
# Python代码示例 - 使用Redis的WATCHMULTI命令实现乐观锁
import redis

def purchase_item(user_id, product_id):
    redis_client = redis.StrictRedis(host='localhost', port=6379, db=0)
    with redis_client.pipeline() as pipe:
        while True:
            try:
                # 监视商品库存
                pipe.watch(f'product:{product_id}:stock')

                # 获取当前库存
                current_stock = int(pipe.get(f'product:{product_id}:stock') or 0)

                if current_stock > 0:
                    # 开始Redis事务
                    pipe.multi()

                    # 扣减库存
                    pipe.decr(f'product:{product_id}:stock')

                    # 执行Redis事务
                    pipe.execute()

                    # 购买成功
                    print(f"User {user_id} purchased product {product_id}. Remaining stock: {current_stock - 1}")
                    break
                else:
                    # 库存不足,取消监视,退出循环
                    pipe.unwatch()
                    print(f"User {user_id} attempted to purchase product {product_id}, but it's out of stock.")
                    break
            except redis.WatchError:
                # 被监视的键被其他客户端修改,重新尝试
                continue

使用乐观锁和版本号: 在MySQL中,可以使用乐观锁和版本号机制,通过在更新语句中增加版本号的判断,确保并发更新时只有一个事务可以成功执行。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
-- MySQL更新语句示例
UPDATE products SET stock = stock - 1, version = version + 1 WHERE id = 123 AND version = 1;

这里,version字段的值会在每次更新时递增,如果在更新时发现version不匹配,则表示有其他事务已经修改了数据,更新将不会执行。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2025-01-20,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
redis与mysql的数据一致性问题(事务一致性)
案例:考虑一个在线购物应用,其中有一个购物车服务,购物车信息存储在MySQL中,同时为了提高性能,购物车中的商品数量也被缓存到了Redis。用户在购物车中添加商品时,需要保证购物车数量在MySQL和Redis中的更新是原子性的,以避免不一致的情况。
GeekLiHua
2025/01/21
1450
SpringBoot实现并发、超发和锁机制/抢购示例:超发、乐观锁、悲观锁和Redis的使用
上述的超发现象,归根到底在于数据库时被多个线程同时访问的,在没有加锁的情况下,上述代码并不是线程安全的。
用户10175992
2022/11/15
1.1K0
SpringBoot实现并发、超发和锁机制/抢购示例:超发、乐观锁、悲观锁和Redis的使用
2025春招,高级程序员回答数据库问题
以下是V 哥对2025年数据库相关高频面试题的汇总整理,结合了MySQL的核心知识点和大厂实际考察方向,涵盖索引、事务、存储引擎、锁机制、优化策略等关键内容。
威哥爱编程
2025/02/10
2430
redis与mysql的数据一致性问题( 网络分区)
在分布式系统中,网络分区是一个常见的挑战,可能导致不同节点之间的通信中断。当涉及到Redis与MySQL这样的数据存储系统时,网络分区可能引发数据不一致性的问题。本文将深入讨论网络分区带来的数据一致性问题,并提供具体的代码和案例,介绍如何有效地应对这些挑战。
GeekLiHua
2025/01/21
1180
MySQL 乐观锁与悲观锁
悲观锁(Pessimistic Lock),顾名思义,就是很悲观,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会block直到它拿到锁。 悲观锁:假定会发生并发冲突,屏蔽一切可能违反数据完整性的操作。 Java synchronized 就属于悲观锁的一种实现,每次线程要修改数据时都先获得锁,保证同一时刻只有一个线程能操作数据,其他线程则会被block。
技术从心
2019/08/06
2K0
MySQL 乐观锁与悲观锁
redis事务
本文记录一些redis事务相关的原理。 1、基本概念 1)什么是redis的事务? 简单理解,可以认为redis事务是一些列redis命令的集合,并且有如下两个特点: a)事务是一个单独的隔离操作:事务中的所有命令都会序列化、按顺序地执行。事务在执行的过程中,不会被其他客户端发送来的命令请求所打断。 b)事务是一个原子操作:事务中的命令要么全部被执行,要么全部都不执行。 2)事务的性质ACID 一般来说,事务有四个性质称为ACID,分别是原子性,一致性,隔离性和持久性。 a)原子性atomicity:red
用户1225216
2018/03/05
6510
redis与mysql的数据一致性问题(概述)
案例: 考虑一个电子商务应用,用户在MySQL中完成订单支付后,订单状态应该即时更新到Redis以提供快速的查询。然而,由于异步同步的延迟,用户可能在Redis中看到过期的订单状态,导致不一致。
GeekLiHua
2025/01/21
1620
一文带你了解MySQL中常见锁(附案例)
在最近字节的面试中,面试管问了一个问题:你所知道的,MySQL都支持哪些锁?当时回答的不是特别好,因此写下这篇文章做个记录。方便自己复盘以及帮助各正在面试的小伙伴们。
祁画
2024/07/25
1940
一文带你了解MySQL中常见锁(附案例)
Redis与MQ如何保证秒杀链路中的事务一致性
在当今互联网时代,秒杀活动成为了各大电商平台吸引用户的重要手段。然而,秒杀活动的高并发场景对系统的性能和稳定性提出了巨大的挑战。为了保证秒杀链路中的事务一致性,我们需要借助Redis和MQ这两个强大的工具。本文将详细介绍Redis与MQ如何保证事务一致性,并给出相应的代码demo。
疯狂的KK
2023/09/04
1.2K0
Redis与MQ如何保证秒杀链路中的事务一致性
拼多多二面:高并发场景扣减商品库存如何防止超卖?
相信大家都参与过某某电商的抢购活动,那么大家有没有思考过,在高并发场景下,如何防止商品超卖?这里需要注意哪些问题?
码哥字节
2025/03/11
2550
拼多多二面:高并发场景扣减商品库存如何防止超卖?
Redis实现乐观锁继而实现抢红包功能
回去之后搜了一下解决方法,其中的一种解决方法就是通过给数据库加锁,也可以防止库存超卖的情况
名字是乱打的
2022/05/13
4650
高并发案例 - 库存超发问题
第一个购买请求来了,想买2个,从数据库中读取到库存有3个,数量够,可以买,减库存后,更新库存为1个。
dys
2019/03/07
3.2K2
数据库事务与锁机制学习
事务与锁是数据库保证数据一致性和处理高并发的核心技术。可以避免脏数据、处理并发冲突,并设计出高效安全的数据库应用。
IT咸鱼
2025/05/20
1420
数据库事务与锁机制学习
聊聊乐观锁与悲观锁
在MySQL中,悲观锁依赖数据库提供的锁机制来实现。在InnoDB引擎中,使用悲观锁需要先关闭MySQL数据库的自动提交属性,然后通过select ... for update来进行加锁。
@派大星
2024/05/20
1930
聊聊乐观锁与悲观锁
PHP高并发情形下怎么防止商品库存超卖
商城系统中,抢购和秒杀是很常见的营销场景,在一定时间内有大量的用户访问商场下单,主要需要解决的问题有两个:
超级小可爱
2023/02/20
3.3K0
✅日活3kw的实际库存业务场景中的超卖到底怎么解决的
这个问题其实可以说是随便一百度几乎可以出来全是解决方案,其实超卖问题再实际业务场景中是十分复杂的。没有什么绝对的解决方案。都是因人而异的。
@派大星
2024/03/08
2970
PHP解决高并发问题
举个例子,高速路口,1秒钟来5部车,每秒通过5部车,高速路口运作正常。突然,这个路口1秒钟只能通过4部车,车流量仍然依旧,结果必定出现大塞车。(5条车道忽然变成4条车道的感觉)
全栈程序员站长
2022/09/04
1.4K0
PHP解决高并发问题
秒杀安全
简介 我们通常衡量一个Web系统的吞吐率的指标是QPS(Query Per Second,每秒处理请求数),解决每秒数万次的高并发场景,这个指标非常关键。举个例子,我们假设处理一个业务请求平均响应时间为100ms,同时,系统内有20台Web服务器,配置MaxClients为500个(表示服务器的最大连接数目)。 那么,我们的Web系统的理论峰值QPS为(理想化的计算方式): 20*500/0.1 = 100000 (10万QPS) 在高并发的实际场景下,机器都处于高负载的状态,在这个时候平均响应时间
架构师小秘圈
2018/04/02
3.4K0
秒杀安全
Redis如何实现乐观锁
大多数是基于数据版本(version)的记录机制实现的。即为数据增加一个版本标识,在基于数据库表的版本解决方案中,一般是通过为数据库表增加一个”version”字段来实现读取出数据时,将此版本号一同读出,之后更新时,对此版本号加1。此时,将提交数据的版本号与数据库表对应记录的当前版本号进行比对,如果提交的数据版本号大于数据库当前版本号,则予以更新,否则认为是过期数据。redis中可以使用watch命令会监视给定的key,当exec时候如果监视的key从调用watch后发生过变化,则整个事务会失败。也可以调用watch多次监视多个key。这样就可以对指定的key加乐观锁了。注意watch的key是对整个连接有效的,事务也一样。如果连接断开,监视和事务都会被自动清除。当然了exec,discard,unwatch命令都会清除连接中的所有监视。
Bug开发工程师
2018/12/05
3.5K0
以超卖为例✨各种场景下如何防止并发污染数据?
比如:商品库存扣减、用户余额调整、火车票、机票、演唱会入场票的扣减(类似商品库存扣减)等...
菜菜的后端私房菜
2024/08/13
3041
推荐阅读
相关推荐
redis与mysql的数据一致性问题(事务一致性)
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验