Redis-09-Redis事务

14 篇文章 0 订阅

说明

  • Redis-09-Redis事务
  • 包括Redis事务特性、事务执行过程、事务冲突问题、连接超时问题、超卖问题、秒杀完库存遗留问题
  • 官方文档:https://redis.io/documentation
  • Redis命令参考:http://redisdoc.com/

核心概念

》什么是Redis事务?

  • 串联多个命令,防止别的命令插队
  • Redis事务跟MySQL不同,不具备ACID功能,仅仅是相当于一个批量组队操作或者类似于管道操作。

》Redis事务特性

  • 单独隔离操作
  • 没有隔离级别
  • 不保证原子性

》Redis事务执行过程

  • 组队阶段(multi)
    • 开启事务后,将此后收到的所有的命令加入一个预执行命令组队队列,而不真正执行
    • 未收到开始执行命令前,只要不报错就不影响整个队列命令的执行,反之任何一个命令报错就会结束组队,从而取消整个预处理命令队列
  • 执行阶段(exec)
    • 收到开始执行命令后,按预处理命令队列进行顺序执行,中间任意一个命令报错都不会影响整个组队的队列
  • 撤销执行(discard)
    • 收到撤销命令后,取消全部预处理命令队列中所有命令的执行

》事务冲突问题

  • 悲观锁
    • 所有人操作同一个锁,性能相对较差
    • 比如可以用setnx方式实现
  • 乐观锁
    • 给数据增加版本号,但是不加锁,最终执行完业务逻辑,需要先修改版本号再提交事务,如果版本号与起初拿到的版本号不同则取消提交事务,从而整个命令执行失败
    • 乐观锁适用于多读场景,相对能一定程度提高性能
    • 乐观锁的实现方式
      • 核心步骤:通过监视(watch)某个key来实现
      • 先设置一个用于被监听的key
      • 开启事务前先监视该key
      • 注意:必须多个客户端并行执行事务时才有效果(这是废话)
      • 退出监视(unwatch)

》连接超时问题

  • 使用连接池pool

》超卖问题

  • 开启事务multi
  • 开启乐观锁,watch监视,只有事务成功后才成功

》秒杀完库存遗留问题

  • 使用乐观锁会造成库存遗留问题
  • 解决方案:使用lua脚本,将多个Redis命令一次提交给Redis执行

操作步骤

》事务执行场景

  • 场景一:正常创建事务并执行
    127.0.0.1:6379> flushdb
    OK
    127.0.0.1:6379> multi
    OK
    127.0.0.1:6379> set k1 v1
    QUEUED
    127.0.0.1:6379> set k2 v2
    QUEUED
    127.0.0.1:6379> exec
    1) OK
    2) OK
    
  • 场景二:创建事务后组队报错,整个事务执行失败
    127.0.0.1:6379> multi
    OK
    127.0.0.1:6379> set k1 v1
    QUEUED
    127.0.0.1:6379> set k1
    (error) ERR wrong number of arguments for 'set' command
    127.0.0.1:6379> exec
    (error) EXECABORT Transaction discarded because of previous errors.
    
  • 场景三:创建事务后组队成功,执行报错,整个事务执行成功
    127.0.0.1:6379> multi
    OK
    127.0.0.1:6379> set k1 v1
    QUEUED
    127.0.0.1:6379> incr k1
    QUEUED
    127.0.0.1:6379> exec
    1) OK
    2) (error) ERR value is not an integer or out of range
    
  • 场景四:创建事务后取消执行
    127.0.0.1:6379> multi
    OK
    127.0.0.1:6379> set k1 v1
    QUEUED
    127.0.0.1:6379> set k2 v2
    QUEUED
    127.0.0.1:6379> discard
    OK
    127.0.0.1:6379> keys *
    (empty list or set)
    

》事务冲突问题场景

  • 乐观锁
    • setnx实现,就不演示了
  • 悲观锁
    • 客户端A(先执行的所以最终成功)
      127.0.0.1:6379> set k 1
      OK
      127.0.0.1:6379> watch k
      OK
      127.0.0.1:6379> multi
      OK
      127.0.0.1:6379> incr k
      QUEUED
      127.0.0.1:6379> exec
      1) (integer) 2
      
    • 客户端B(后执行的所以最终失败)
      127.0.0.1:6379> watch k
      OK
      127.0.0.1:6379> multi
      OK
      127.0.0.1:6379> incr k
      QUEUED
      127.0.0.1:6379> exec
      (nil)
      
    • 退出监视
      127.0.0.1:6379> unwatch
      OK
      
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值