• 2022/08/25 day10:Redis 事务


    目录

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-52s3egvf-1661511029228)(en-resource://database/5237:1)]
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZNWo2Plu-1661511029229)(en-resource://database/5239:1)]

    事务简介

    乱入的小朋友

    收银员查数的过程被小朋友打乱了
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uRv2u1oq-1661511029229)(en-resource://database/5241:1)]

    解决办法:让她在安静的环境下做就行了。

    什么是事务
    【问题】Redis执行过程中,多条连续执行的指令被干扰,打断,插队
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-arVtn6Wl-1661511029230)(en-resource://database/5243:1)]
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9zf1CzxT-1661511029230)(en-resource://database/5245:1)]
    这个问题当然要解决,就依赖事务。

    Redis事务就是一个命令执行的队列,将一系列预定义命令包装成一个整体(一个队列)。当执行时,一次性按照添加顺序依次执行,中间不会被打断或者干扰。

    事务基本操作

    事务的边界
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GKwdsDKy-1661511029230)(en-resource://database/5247:1)]

    事务的基本操作

    • 开启事务:multi

    • 作用

      • 设定事务的开启位置,此指令执行后,后续的所有指令均加入到事务中
    • 执行事务:exec

    • 作用

      • 设定事务的结束位置,同时执行事务。与multi成对出现,成对使用。
    • 注意

      • 加入事务的命令暂时进入到队列中,并没有立即执行,只要执行exec命令才开始执行。

    (已经常见的虚拟机文件是以.vmx结尾)
    演示:
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-i7C5QQIw-1661511029231)(en-resource://database/5249:1)]

    • 准备阶段
      • 查看进程
        • ps -ef | grep redis-
      • 杀死进程
        • kill -s 9 4155
      • 重启进程
        • redis-server conf/redis-6379.conf
      • 查看进程
        • ps -ef | grep redis-
    • 事务
      • 连接redis
        • redis-cli
      • [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CLdONbGw-1661511029231)(en-resource://database/5251:1)]

    【疑问】事务定义过程中发现出了问题,怎么办?

    • 取消事务:discard
    • 作用
      • 终止当前事务的定义,发生在multi之后,exec之前
    • 演示
      • [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Pejy5nbJ-1661511029231)(en-resource://database/5253:1)]

    事务的工作流程

    set–>multi–>set–>exec–>discard
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tnic5yV2-1661511029232)(en-resource://database/5255:1)]
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FH6PITRO-1661511029232)(en-resource://database/5257:1)]

    事务的注意事项

    1. 【疑问】定义事务的过程中,命令格式输入错误怎么办?
    • 语法错误

      • 指命令书写格式错误
    • 处理错误

      • 如果定义的事务中所包含的命令存在语法错误,整体事务中所有命令均不会执行。包括那些语法正确的命令。
    • 演示

      • 清楚redis客户端中所有数据
        • flushdb
      • 来查看一下
        • keys * 现在什么都没有了
      • 事务中有命令错误一次,事务就不存在了,让你再重新开一个事务(命令中有命令存在语法错误,那么本次事务中所有命令都不得执行)
        • [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JNxx2AB4-1661511029232)(en-resource://database/5259:1)]
    1. 【疑问】定义事务的过程中,命令执行出现错误怎么办?
    • 运行错误
      • 指命令格式正确,但是无法正确执行。例如对list进行incr操作
      • 语法上没问题,是否是逻辑错误?
    • 处理结果
      • 能够正确运行的命令会执行,运行错误的命令不会执行。也就是正确的命令执行,错误的不执行。
    • 演示
      • 重新开一个事务
        • multi
      • 事务中,语法都不错,逻辑正确的执行,逻辑错误的不执行
        • [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lKwGQaRg-1661511029233)(en-resource://database/5261:1)]
    • 注意
      • 已经执行完毕的命令对应的数据不会自动回滚,需要程序员自己在代码中实现回滚。
        • 其他数据库中的回滚:事务中只要存在错误,就会回滚命令到开启事务之前,所谓是“一‘招’回到解放前”。
      • 这个问题是本应该避免掉的:你不可能这个程序不测试就上线跑。但如果出现,应该怎么解决呢?【手动代码回滚–鸡肋】
        • [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gN9KKae0-1661511029233)(en-resource://database/5265:1)]

    基于特定条件的事务执行——锁

    业务场景

    天猫双十一,热卖过程中,对已经售罄的货物追加补货,4个业务员都有权限进行补货。补货的操作可能是一系列的操作,牵扯到多个连续操作,如何保障不会重复操作?

    • 问题来了:他们四个人能不能同时补货?不行,只能一个人补;
      • 如果小张补完货了,小凯再补的时候,发现补好了,他就不用操作了。
      • 那么怎么实现这个操作呢?–业务分析

    业务分析

    • 多个客户端有可能同时操作同一组数据,并且该数据一旦被操作修改后,将不适用于继续操作
    • 在操作之前要操作的数据,一旦发生变化,终止当前的操作
    • 解决办法:就是客户端对数据进行监控。如果key发生了变化,我就执行,没变化就不执行。

    解决方案

    • 对key添加监视锁,在执行exec前如果key发生了变化,终止事务的执行

      • watch key1 [key2…]
    • 取消对所有key的监视

      • unwatch
    • 演示

      • 为了我们实验效果不被影响,我们所有数据全都清掉
        • flushdb
      • 来查看一下
        • keys * 现在什么都没有了
      • 设置两个值,用来监控
        • set name 123
        • set age 321
      • 监控一个
        • watch name
        • 监控的东西一旦发生改变,下面定义的事务就不会再执行了
          • [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LrXcJV5L-1661511029233)(en-resource://database/5271:1)]
        • 解释那四个业务员:一旦有人把货物改变了,那么此业务员的补货就不会再执行了(监控完了后,第一个人把它改变了,后面的人改变就不会执行了)
      • 注意:
        • 不能在事务里面watch(告诉你不行,会出现错误)
    • 取消事务,放弃执行事务块内的所有命令

      • discard
    • 监控name

      • watch name
      • get name
      • unwatch 取消所有的锁
      • 另一边改变name
      • exec 就可以执行了

    tips 18:
    redis应用基于状态控制的批量任务执行

    基于特定条件的事务执行1

    业务场景

    天猫双11热卖过程中,对已经售罄的货物追加补货,且补货完成。客户购买热情高涨,3秒内将所有的商品购买完毕。本次补货已经将库存全部清空,如何避免最后一件商品不被多人购买?【超卖问题】

    业务分析

    • 使用watch监控一个key有没有改变已经不能解决问题,此处要监控的是具体数据
    • 虽然redis是单线程的,但是多个客户端对同一数据同时进行操作时,如何避免不被同时修改?

    解决方案

    • 使用setnx设置一个公共锁(公共厕所)
      • setnx lock-key valye
        利用setnx命令的返回值特征,有值则返回设置失败,无值则返回设置成功
      • 对于返回设置成功的,拥有控制权,进行下一步的具体业务操作‘’
      • 对于返回设置失败的,不具有控制权,排队或等待
        操作完毕通过del操作释放锁

    注意:上述解决方案是一种设计概念,依赖规范保障,具有风险性。

    • 演示
      • 清空所有数据
        • flushdb
      • 查看数据
        • keys *
      • key一旦被锁上,就可以操作,则其他客户端redis不能操作。
        • [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2NJ1pbzv-1661511029233)(en-resource://database/5273:1)]

    tips 19:
    redis应用基于分布式锁对应的场景控制

    基于特定条件的事务执行2

    业务场景

    依赖分布式锁的机制,某个用户操作时对应客户端宕机,且此时已经获取到锁。如何解决?(宕机前加锁,宕机后锁还在,此时求排队的人心理阴影)所以得给锁加个时效,也就是说你这个锁只能在时效内有效。那么你在厕所里睡觉,它的门还能自己给开了(不会?砸锁行不,不管你尴尬否))

    业务分析

    • 由于锁操作由用户控制加锁解锁,必定会存在加锁后未解锁的风险
    • 需要解锁操作不能仅依赖用户控制,系统级别要给出对应的保底处理方案

    解决方案

    • 使用expire 为锁key添加时间限定,到时不释放,则放弃锁(锁时效)(其实就是商场内的寄存空间/杜绝占着茅坑不拉屎的行为)

      • expire lock-key second 秒
      • pexpire lock-key milliseconds
        由于操作通常都是微秒级或毫秒级,因此该锁定时间不宜设置过大。具体时间需要业务测试后确认
      • 例如:持有锁的操作最长执行时间127ms,最短执行时间7ms
      • 测试百万次最长执行时间对应命令的最大耗时,测试百万次网络延迟平均耗时
      • 锁时间设定推荐:最大耗时* 120% + 平均网络延迟 * 110%
      • 如果业务最大耗时<<网络平均延迟,通常为2个数量级,取其中单个耗时较长即可
    • 演示

      • 清空所有数据
        • flushdb
      • 查看数据
        • keys *
      • 要求你在锁的时候,马上加上时限
        • set name 123
        • setnx lock-name 1
        • expire lock-name 20 20秒

    总结

    在这里插入图片描述

                                                                                     ——此文档为学习笔记!
    
    • 1
  • 相关阅读:
    uniapp调用接口渲染的问题
    C++并发编程
    计算机网络——数据链路层(滑动窗口协议: 选择重传)(点对点协议 PPP)
    Worthington丨Worthington胶原酶原材料认证
    程序分析与优化 - 8 寄存器分配
    HTML5+CSS3+JS小实例:使用L2Dwidget实现二次元卡通看板娘
    软件评测师之总线
    MybatisPlus分页插件使用
    JS前端实现身份证号码合法性校验(校验码校验)
    智慧金融-数据可视化
  • 原文地址:https://blog.csdn.net/w2079930908/article/details/126548861