Redis事务与锁机制在并发秒杀场景的深入剖析

十. Redis 事务与 “锁机制”——并发秒杀处理的详细阐述

目录

  • 十. Redis 事务与 “锁机制”——并发秒杀处理的详细阐述
  • 1. Redis 事务的定义
  • 2. Redis 事务的三大特性
  • 3. Redis 事务相关指令 Multi、Exec、discard 及 “watch & unwatch”
    • 3.1 快速入门(演示 Redis 事务控制)
    • 3.2 注意事项与细节
  • 4. Redis 事务冲突及解决办法(悲观锁,乐观锁) watch & unwatch
    • 4.1 “悲观锁” 解决
    • 4.2 “乐观锁” 解决
    • 4.3 watch & unwatch
  • 5. 案例演示:火车票-抢票(解决超卖,库存遗留)问题
    • 5.1 案例思路分析:
    • 5.2 完成基本购票流程,暂不考虑事务与并发问题
    • 5.3 抢票并发模拟,出现超卖问题
    • 5.4 Redis 连接池技术
    • 5.5 利用 Redis 的事务机制,解决超卖问题(使用 watch,multi )
    • 5.6 抢票并发模拟,分析库存遗留问题
    • 5.7 运用 LUA 脚本(解决超卖,和库存遗留问题)
  • 6. 总结:

1. Redis 事务的定义

  1. Redis事务是一种独立的隔离性操作:事务内的所有命令会被依次序列化,并按顺序执行。
  2. 在事务执行过程中,不会被其他客户端发送的命令请求打断。
  3. Redis事务的主要作用是将多个命令串联起来,防止其他命令插队执行。

2. Redis 事务的三大特性

  1. 独立的隔离操作

    1. Redis事务是独立的隔离性操作,其中所有命令会被序列化并按顺序执行。
    2. 在事务执行过程中,不会被其他客户端发送的命令请求打断。
  2. 无隔离级别概念

    队列中的命令在未提交前不会实际执行。

  3. 不保证原子性

    事务执行时,若有指令失败,其他指令仍会继续执行,不存在回滚机制。

    MySQL事务支持回滚,而Redis事务不支持回滚。

3. Redis 事务相关指令 Multi、Exec、discard 及 “watch & unwatch”

3.1 快速入门(演示 Redis 事务控制)

127.0.0.1:6379> multi
127.0.0.1:6379(TX)> set k1 v1
QUEUED
127.0.0.1:6379(TX)> set k2 v2
QUEUED
127.0.0.1:6379(TX)> set k3 v3
QUEUED
127.0.0.1:6379(TX)> exec

3.2 注意事项与细节

  1. 组队阶段可通过 discard 放弃组队,需在 [TX] 队列且未执行 exec 命令前有效。
  2. 若组队阶段出现命令输入等错误,会导致 exec 失败,事务所有指令不执行。
  3. 组队成功但指令执行异常时,exec 提交会出现部分成功部分失败情况,Redis事务不具原子性。

4. Redis 事务冲突及解决办法(悲观锁,乐观锁) watch & unwatch

以抢票问题为例:多个用户同时请求购票,若不处理会出现超卖。

4.1 “悲观锁” 解决

悲观锁认为每次获取数据时其他会修改,因此获取数据前上锁。传统关系型数据库的行锁、表锁等即属此类。

4.2 “乐观锁” 解决

乐观锁认为获取数据时其他不会修改,更新时检查版本等。Redis利用 check-and-set 机制实现事务。

4.3 watch & unwatch

  1. 基本语法: watch key [key ...]
  2. 执行 multi 前用 watch 监视key,若事务执行前key被修改,事务中断。
  3. unwatch 取消对所有key的监视,若已执行 execdiscard,无需再用。

5. 案例演示:火车票-抢票(解决超卖,库存遗留)问题

5.1 案例思路分析:

通过WEB项目演示,需保证一个用户只能购一张票、无超购、无库存遗留。

5.2 完成基本购票流程,暂不考虑事务和并发问题

编写Java Web项目,引入相关jar包和jquery,创建index.jsp等。

5.3 抢票并发模拟,出现超卖问题

使用ab工具模拟并发请求,测试超卖情况。

5.4 Redis 连接池技术

连接池节省连接消耗,配置MaxTotal、maxIdle等参数。

5.5 利用 Redis 的事务机制,解决超卖问题(使用 watch,multi )

通过 watch 监控库存,使用事务完成秒杀。

5.6 抢票并发模拟,分析库存遗留问题

大量并发请求可能导致库存遗留,因乐观锁机制部分请求被打断。

5.7 运用 LUA 脚本(解决超卖,和库存遗留问题)

LUA脚本具原子性,解决多任务并发问题。LUA脚本示例:

local userid=KEYS[1];
local ticketno=KEYS[2];
local stockKey='sk:'..ticketno..":ticket";
local usersKey='sk:'..ticketno..":user";
local userExists=redis.call("sismember",usersKey,userid);
if tonumber(userExists)==1 then
   return 2;
end
local num= redis.call("get" ,stockKey);
if tonumber(num)<=0 then
   return 0;
else
   redis.call("decr",stockKey);
   redis.call("sadd",usersKey,userid);
end
return 1

6. 总结:

在本部分,感谢读者的关注与支持,将继续在相关领域探索,期待与读者再次相遇。

文章整理自互联网,只做测试使用。发布者:Lomu,转转请注明出处:https://www.it1024doc.com/12530.html

(0)
LomuLomu
上一篇 2025 年 6 月 18 日
下一篇 2025 年 6 月 18 日

相关推荐

  • 永久pycharm激活码安装视频+最新pycharm破解方法

    申明:本教程Pycharm 破解补丁、激活码均收集于网络,请勿商用,仅供个人学习使用,如有侵权,请联系作者删除。若条件允许,希望大家购买正版 ! 废话不多说,先上 Pycharm2025.2.1 版本破解成功的截图,如下图,可以看到已经成功破解到 2099 年辣,舒服的很! 接下来就给大家通过图文的方式分享一下如何破解最新的Pycharm。 如果觉得破解麻烦…

    PyCharm激活码 2026 年 1 月 1 日
    35800
  • ChatGPT Plus微信支付宝充值操作指南

    如果只是想正常使用 ChatGPT Plus,最麻烦的往往不是账号注册,而是怎么完成订阅。国内用户不想碰虚拟卡,也不愿意买共享号,就需要更直接的充值方式。可以按下面步骤操作:先用国内支付购买充值卡密,再在充值页面验证卡密并确认账号信息。

    未分类 2026 年 7 月 10 日
    8400
  • Claude Pro代充微信支付宝教程

    国内用户如何充值Claude Pro?本文整理Claude充值、Claude代充、国内充值Claude的完整操作流程,支持支付宝和微信开通Claude Pro。

    未分类 3天前
    2200
  • 数据密集型应用系统设计PDF、EPUB免费下载

    适读人群 :所有后端开发者 英国剑桥大学分布式系统研究员力作,微软CTO联袂力荐,EMC资深架构师亲译。带你跨越从分布式理论到工程实践的鸿沟! 电子版仅供预览,支持正版,喜欢的请购买正版书籍 点击原文去下载 书籍信息 作者: Martin Kleppmann出版社: 中国电力出版社原作名: Designing Data-Intensive Applicati…

    2025 年 1 月 13 日
    71000
  • 使用 gt-checksum 迁移表结构到 GreatSQL

    将数据库表结构迁移至 GreatSQL 的指南 引言 本文旨在指导如何利用 gt-checksum 工具,将数据库表结构从 ORACLE 迁移至 GreatSQL。 gt-checksum 简介 gt-checksum 是 GreatSQL 社区开发的开源静态数据库校验和修复工具,它支持包括 MySQL 和 Oracle 在内的多种主流数据库系统。其商业版本…

    未分类 2024 年 12 月 24 日
    76700

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信