前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Redis中的事务、锁机制(乐观锁、悲观锁)

Redis中的事务、锁机制(乐观锁、悲观锁)

作者头像
百思不得小赵
发布2022-12-01 14:54:32
1.1K0
发布2022-12-01 14:54:32
举报
文章被收录于专栏:小赵Java总结
在这里插入图片描述
在这里插入图片描述

文章目录


事务,这个名词相信大家已经非常熟悉了,在关系型数据库MySQL中、对于事务的定义:一个事务是一个完整的业务逻辑单元,不可再分。在一次事务中,多条DML语句,要么全部执行成功,要么全部执行失败,Spring框架中提出了声明式事务的概念等等。可见,事务在日常的开发中是非常重要的存在。那么,Redis中是如何定义事务呢?让我们一探究竟。

一、Redis事务概述

  • Redis事务是一个单独的隔离操作:事务中的所有命令都会序列化、按顺序地执行。事务在执行的过程中,不会被其他客户端发送来的命令请求所打断。
  • Redis事务的主要作用就是串联多个命令防止别的命令插队。
在这里插入图片描述
在这里插入图片描述

Redis中进行事务操作的时候,将多个操作先进行序列化,按照每个操作顺序进行执行,如果在操作的过程中,有别的操作进行插队,那么是不允许的,别的指令不能插入到操作中,所以事务操作是相互隔离的。

二、事务操作

相关指令

  • Multi:表示开启事务。开启后输入的命令都会依次进入命令队列中,但不会立即执行。
  • Exec:将之前的命令队列中的命令依次执行。
  • Discard:组队的过程中可以通过discard来放弃组队。
在这里插入图片描述
在这里插入图片描述

从输入Multi命令开始,输入的命令都会依次进入命令队列中,但不会执行,直到输入Exec后,Redis会将之前的命令队列中的命令依次执行。组队的过程中可以通过discard来放弃组队。

案例操作: 进入开启Redis服务的服务器

在这里插入图片描述
在这里插入图片描述

从上图可以看到,三个入队的操作全部执行成功,并且按照顺序依次执行。

放弃组队:

在这里插入图片描述
在这里插入图片描述

错误处理

① 组队中某个命令出现了报告错误,执行时整个的所有队列都会被取消。

在这里插入图片描述
在这里插入图片描述

案例操作:

在这里插入图片描述
在这里插入图片描述

② 如果执行阶段某个命令报出了错误,则只有报错的命令不会被执行,而其他的命令都会执行,不会回滚。

在这里插入图片描述
在这里插入图片描述

案例操作:

在这里插入图片描述
在这里插入图片描述

三、锁机制解决事务冲突

事务冲突

模拟一次双十一购物的场景:

在某年的双十一期间,小王的前女友、现任女友和小王同时使用你的银行卡去抢购商品。小王自己账户总共1万元,前任女友想要给她的现任男友买一部苹果手机,于是用小王的账户花费8000元买了手机,这时小王的账户剩下2000元,然后小王的现任女友知道小王账户有一万元,于是花费5000元买了一款喜欢的包包,这时账户剩下 -3000元,最后,由于小王特别喜欢吃康师傅老坛酸菜牛肉面,于是乎花费掉1000元买了酸菜面,至此,小王的账户剩下余额 -4000元。

在这里插入图片描述
在这里插入图片描述

我们知道,在正常的生活场景中以上的事情是不会发生的,账户不可能所剩余额为负数,当余额不足以支付其他商品时,应该无法进行相关操作,这就是由于没有进行事务操作,出现了事务冲突的问题。那么怎样解决事务的冲突问题呢,Redis中引入锁的机制来解决。

悲观锁

悲观锁(Pessimistic Lock),就是很悲观,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会block直到它拿到锁。传统的关系型数据库里边就用到了很多这种锁机制,比如行锁,表锁等,读锁,写锁等,都是在做操作之前先上锁。

在这里插入图片描述
在这里插入图片描述

通俗的说:

小王账户中有10000元,小王的前女友在操作的时候,先进行上锁,上锁后其他人就无法对小王的账号进行操作,也就是说,小王的前女友买苹果手机的时候,小王的现任女友和小王对账户发起的操作请求处于阻塞状态。前任女友操作完后释放锁,账户减8000,余额2000。 小王的现任女友在买包包时,账户为2000元,进行买包操作时,先进行上锁,上锁后,小王无法进行操作处于阻塞状态,现任女友想买5000的包包发现余额不够,最终不能操作,释放锁,小王继续操作。以此类推,解决了账户最终余额为负数的问题,也就是事务冲突问题。

引起的缺点就是:效率非常低,一个请求在操作的时候,其他的请求只能等待。

乐观锁

乐观锁(Optimistic Lock),就是很乐观,每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据,可以使用版本号等机制。乐观锁适用于多读的应用类型,这样可以提高吞吐量。Redis就是利用这种check-and-set机制实现事务的。

在这里插入图片描述
在这里插入图片描述

通俗的说:

小王账户中有10000元,小王的前女友在操作的时候,先给数据加上一个字段version(版本号),例如第一次操作的时候版本号为 V1.0,小王的现任女友和小王都可以得到 V1.0版本的数据。由于小王的前女友手速非常快,先购买了苹果手机,账户减去8000元,余额2000元,此时数据库在修改数据的时候,同时修改数据对应的版本号为 V 1.1。此时,小王的现女友和小王进行购买的时候,先会去检查下当前的数据版本号与数据库中的版本号是否一致,版本号一致进行操作,不一致无法进行操作。

命令操作

①.WATCH key [key …]

在执行multi之前,先执行watch key1 [key2],可以监视一个(或多个) key ,如果在事务执行之前这个(或这些) key 被其他命令所改动,那么事务将被打断。

在这里插入图片描述
在这里插入图片描述

② UNWATCH

取消 WATCH 命令对所有 key 的监视。如果在执行 WATCH 命令之后,EXEC 命令或DISCARD 命令先被执行了的话,那么就不需要再执行UNWATCH 了。

在这里插入图片描述
在这里插入图片描述

四、Redis事务的特性

  • 单独的隔离操作 事务中的所有命令都会序列化、按顺序地执行。事务在执行的过程中,不会被其他客户端发送来的命令请求所打断。
  • 没有隔离级别的概念 队列中的命令没有提交之前都不会实际被执行,因为事务提交前任何指令都不会被实际执行。
  • 不保证原子性 事务中如果有一条命令执行失败,其后的命令仍然会被执行,没有回滚 。

至此Redis中的事务、锁机制(乐观锁、悲观锁)内容就分享完啦,希望对大家有所帮助。

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

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

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

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 文章目录
  • 一、Redis事务概述
  • 二、事务操作
    • 相关指令
      • 错误处理
      • 三、锁机制解决事务冲突
        • 事务冲突
          • 悲观锁
            • 乐观锁
              • 命令操作
              • 四、Redis事务的特性
              相关产品与服务
              云数据库 Redis
              腾讯云数据库 Redis(TencentDB for Redis)是腾讯云打造的兼容 Redis 协议的缓存和存储服务。丰富的数据结构能帮助您完成不同类型的业务场景开发。支持主从热备,提供自动容灾切换、数据备份、故障迁移、实例监控、在线扩容、数据回档等全套的数据库服务。
              领券
              问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档