Redis——事务

embedded/2024/10/22 15:01:27/

文章目录

    • Redis 事务
      • Redis 的事务和 MySQL 事务的区别:
      • 事务操作
        • MULTI
        • EXEC
        • DISCARD
        • WATCH
        • UNWATCH
        • watch的实现原理
      • 总结

Redis 事务

什么是事务

Redis 的事务和 MySQL 的事务 概念上是类似的. 都是把⼀系列操作绑定成⼀组. 让这⼀组能够批量执行

Redis 的事务和 MySQL 事务的区别:

  • 弱化的原子性: redis 没有 “回滚机制”. 只能做到这些操作 “批量执行”. 不能做到 “⼀个失败就恢复到
    初始状态”
  • 不保证⼀致性: 不涉及 “约束”. 也没有回滚. MySQL 的⼀致性体现的是运行事务前和运行后 , 结果都
    是合理有效的, 不会出现中间⾮法状态
  • 不需要隔离性: 也没有隔离级别, 因为不会并发执行事务 (redis 单线程处理请求)
  • 不需要持久性: 是保存在内存的. 是否开启持久化, 是redis-server 自己的事情, 和事务无关

Redis 事务本质上是在服务器上搞了⼀个 “事务队列”. 每次客户端在事务中进行⼀个操作, 都会把命令先
发给服务器, 放到 “事务队列” 中(但是并不会立即执行)
而是会在真正收到 EXEC 命令之后, 才真正执行队列中的所有操作.

因此, Redis 的事务的功能相比于 MySQL 来说, 是弱化很多的. 只能保证事务中的这⼏个操作是 “连续
的”, 不会被别的客户端 “加塞”, 仅此而已.

事务操作

MULTI

开启⼀个事务. 执行成功返回 OK

在这里插入图片描述

EXEC

真正执行事务

在这里插入图片描述

每次添加⼀个操作, 都会提示 “QUEUED”, 说明命令已经进入客户端的队列了. 真正执行 EXEC 的时候, 客户端才会真正把上述操作发送给服务器. 此时就可以获取到上述 key 的值了

在这里插入图片描述

DISCARD

放弃当前事务,此时直接清空事务队列.,之前的操作都不会真正执行到

在这里插入图片描述

WATCH

在执行事务的时候, 如果某个事务中修改的值, 被别的客户端修改了, 此时就容易出现数据不⼀致的问

例如

# 客户端1 先执行
127.0.0.1:6379> MULTI
OK
127.0.0.1:6379> set key 100
QUEUED# 客户端2 再执行
127.0.0.1:6379> set key 200
OK# 客户端1 最后执行
127.0.0.1:6379> EXEC
OK

此时, key 的值是多少呢??

客户端1

在这里插入图片描述

客户端2

在这里插入图片描述

从输⼊命令的时间看, 是客端1 先执行的 set key 100. 客户端2 后执行的 set key 200.

这个时候,就容易发生歧义,watch 命令就是⽤来解决这个问题的,watch 在该客户端上监控⼀组具体的 key

  • 当开启事务的时候, 如果对 watch 的 key 进行修改, 就会记录当前 key 的 “版本号”. (版本号是个简单
    的整数, 每次修改都会使版本变大. 服务器来维护每个 key 的版本号情况)
  • 在真正提交事务的时候, 如果发现当前服务器上的 key 的版本号已经超过了事务开始时的版本号, 就
    会让事务执行失败. (事务中的所有操作都不执行).

客户端1先执行

在这里插入图片描述

然后客户端2执行

在这里插入图片描述

然后再回到客户端1执行

在这里插入图片描述

此时可以发现事务已经被取消了. 这次提交的所有命令都没有执行

# 客户端1
127.0.0.1:6379> watch key  # 开始监控 key
OK
127.0.0.1:6379> multi  
OK
127.0.0.1:6379> set key 100   #进行修改,从服务器获取key的版本号0,记录key的版本号
QUEUED
127.0.0.1:6379> set key2 200
QUEUED# 客户端2 
127.0.0.1:6379> set key 200    # 修改成功, 使服务器端的 k1 的版本号 0 -> 1
OK# 客户端1
127.0.0.1:6379> exec # 真正执⾏修改操作, 此时对⽐版本发现, 客⼾端的 k1 的版本号是 0, 服务器上的版本号是 1, 版本不⼀致! 说明有其他客⼾端在事务中间修改了k1
(nil)
127.0.0.1:6379> get key
"200"
127.0.0.1:6379> get key2  # 事务已经被取消
(nil)
UNWATCH

取消对 key 的监控,相当于 WATCH 的逆操作

watch的实现原理

watch的实现,类似于一个“乐观锁”

乐观锁,悲观锁不是指某个具体的锁,而是指的是某一类锁的特性
乐观锁:加锁之前,就有一个心理预期,预期接下来锁冲突的概率比较低
悲观锁:加锁之前,也有一个心理预期,接下来锁冲突的概率比较高
锁冲突概率高,和冲突概率低,接下来要做的工作是不一样的

  • 当执行watch key的时候,就会给这个key安排一个版本高,版本号可以理解成一个“整数”,每次在修改的时候,版本号都会“变大”
  • 在执行exec时,就会做出判定,判定当前这个key的版本号,和最初watch的时候记录的版本号是否一致,如果一致,说明当前key在事务开启到最终执行的这个过程中,没有别的客户端修改,于是才能真正进行设置,如果不一致,说明key在其他客户端改过了,因此此处就直接丢弃事务中的操作,exec返回nil

总结

Redis的事务,要比mysql的事务简单的多

  1. 原子性:Redis的事务,并不支持回滚
  2. 一致性:Redis并不会保证事务执行前和执行后,内容统一
  3. 持久性:Redis主要通过内存来存储数据
  4. 隔离性:Redis自身作为一个单线程的服务器模型,上面的请求本质上都是串行执行的

http://www.ppmy.cn/embedded/129586.html

相关文章

五台山景点购票系统——后附计算机源码

摘 要 本论文主要论述了如何使用JAVA语言开发一个五台山景点购票系统 ,本系统将严格按照软件开发流程进行各个阶段的工作,采用B/S架构,面向对象编程思想进行项目开发。在引言中,作者将论述五台山景点购票系统的当前背景以及系统开…

安全见闻笔记

目录 安全见闻... 1 编程语言... 1 函数式编程语言... 1 数据科学和机器学习领域... 2 Web 全栈开发... 2 移动开发... 2 嵌入式系统开发... 2 其他... 2 操作系统... 2 裸板程序... 3 操作系统... 3 网络通讯... 4 计算机硬件... 4 网络硬件... 4 移动设备硬件…

机器人如何强化润滑与维护,减少关节磨损?

要强化润滑与维护,以减少人形机器人关节的磨损,可以从以下几个方面着手: 一、选择适宜的润滑剂 根据应用条件选择:根据关节的工作环境、负载、速度等条件选择合适的润滑剂。例如,对于高温或高湿环境,应选择耐高温或耐湿的润滑剂。确保润滑性能:选择具有良好润滑性、抗磨…

BUUCTF re rsa做法(提供enc和key)

首先我们需要安装个一些东西,即gmpy2,Linux安装流程如下 首先安装依赖库 gmp库:apt-get install libgmp-dev mpfr库:apt-get install libmpfr-dev mpc库:apt-get install libmpc-dev 安装gmpy2:pip in…

最新 client-java 调用 k8s ApiServer

创建权限绑定 sa-role.yaml apiVersion: v1 kind: ServiceAccount metadata:name: my-admin #账号名namespace: kube-system--- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata:annotations:rbac.authorization.kubernetes.io/autoupdate: "true…

Neo4j 构建文本类型的知识图谱

Neo4j 是一个强大的图数据库,用于构建和查询各种类型的图数据结构。构建知识图谱是一项常见任务,尤其在处理自然语言处理 (NLP) 和文本信息时。基于 Neo4j,可以将文本数据转换为知识图谱,使得复杂的文本关系以图结构存储&#xff…

UE4 材质学习笔记12(水体反射和折射)

一.水体反射和折射 首先就是要断开所有连接到根节点的线,因为水有很多不同的节点成分,当所有其他节点都在用时 要分辨出其中一个是何效果是很难的。 虚幻有五种不同的方法可以创建反射,虚幻中的大多数场景使用多种这些方法 它们会同时运作。…

数据飞轮:唤醒沉睡的数据中台,驱动企业业务增长的关键

数据飞轮:唤醒沉睡的数据中台,驱动企业业务增长的关键 文章目录 数据飞轮:唤醒沉睡的数据中台,驱动企业业务增长的关键数据驱动的核心:数据消费企业利用数据飞轮唤醒沉睡数据实现数据驱动的技术数据中台人工智能和机器…