【redis】redis事务

目录

Redis事务

  • Redis事务是一种将多个命令打包成一个单独操作的机制,它保证了在执行这些命令期间,其他命令无法插入。

四个命令

Redis事务通过MULTI、EXEC、WATCH和UNWATCH四个命令来实现。

  1. MULTI命令:将Redis进入事务模式,之后所有的命令都会被认为是事务中的命令。在执行MULTI命令后,Redis会返回一个QUEUED响应。

  2. EXEC命令:用于执行事务中的所有命令。在执行EXEC命令之前,Redis会按顺序记录所有事务中的命令,并在执行期间暂停处理其他命令。

  3. WATCH命令:用于监视一个或多个键,当这些键被修改时,事务会被放弃而不执行。WATCH命令可以用来实现乐观锁的机制。

  4. UNWATCH命令:用于解除对键的监视。

事务中的每个命令的执行结果会被返回,但只有在执行EXEC命令后,Redis才会真正执行这些命令。如果在事务执行期间出现错误,Redis不会回滚已经执行的命令,而是继续执行剩余的命令。

redis事务特性

  • 原子性:在事务执行期间,所有的命令要么全部执行成功,要么全部不执行。
  • Redis保证了事务中的命令的原子性,即事务的执行是不可中断的。

与MySQL的事务特性对比来说

  1. 不具备一致性:redis 没有约束和回滚,事务执行一旦出错,就可能导致不一致的情况.
  2. 不具备持久性:Redis 本身就是内存数据库,数据是存储在内存中的. 虽然 Redis 也有持久化机制,但是这里的持久化机制和事务没有什么直接关系.
  3. 不具备隔离性:Redis 是一个单线程模型的服务器程序,所有的请求 / 事务,都是 "串行" 执行的.

redis事务执行原理

Redis事务的执行原理可以简要概括为以下几个步骤:

  1. 事务开启:使用MULTI命令开启一个事务。在事务开始之后,客户端发送的命令都会被暂时存储在一个事务队列中,而不是立即执行。

  2. 命令入队:在事务开启后,客户端可以发送多个命令,这些命令会被依次存储在事务队列中,而不会立即执行。

  3. 事务执行:使用EXEC命令来执行事务中的所有命令。在执行EXEC命令之前,Redis会对事务队列中的所有命令进行一致性检查,确保所有的命令可以顺序执行,并且没有冲突。

  4. 命令执行:Redis按照顺序执行事务队列中的所有命令。执行过程中,Redis会根据具体的命令类型进行相应的操作,比如读取、修改、删除等。

  5. 事务结果返回:执行完所有的命令后,Redis会将事务的执行结果以数组的形式返回给客户端。数组中的每个元素对应一个命令的返回结果。

需要注意的是,在事务执行过程中,如果某个命令执行失败,Redis不会回滚已经执行的命令,而是继续执行剩余的命令。执行结果会以特殊的标识表示失败的命令。

另外,Redis还提供了WATCH命令来实现乐观锁机制。客户端可以在事务开始之前使用WATCH命令监视一个或多个键,如果在事务执行期间,这些键被其他客户端修改,事务就会被中断。这可以用来保证事务的原子性和一致性。

Redis 事务的使用

基本使用

shell 复制代码
multi        开启事务(读作 "猫体")
exec         执行事务
discard      放弃当前事务
watch        监控某个 key 是否在事务执行之前发生变化(必须搭配事务使用)
unwatch      放弃监控
  • 此时开启另一个客户端,查看这几个 key ,会发现这几个 key 并没有被赋值(说明此时还没有执行事务).,如下
  • 如果放弃事务,就相当于什么也没有发生
  • 如果使用 exec,就会按顺序执行事务

watch 监控

  • watch 就是用来监控某个 key 是否在事务执行之前,发生改变,但必须搭配事务来使用.
  • 如下,用 watch 监控 key1,开启事务,并在执行事务之前,另一个客户端对 key1 进行修改
  • 执行事务后,发现 key 在外部由修改,会返回 nil ,表示事务什么都不会执行,如下

watch 实现原理

在Redis中,watch命令用于在事务中监视一个或多个键,以确保在事务执行期间这些键没有被其他客户端修改。如果在执行事务期间有任何被监视的键发生了变化,事务将被中断并返回错误。

watch命令的实现原理如下:

  1. 客户端发送watch命令给Redis服务器,指定要监视的键。
  2. Redis服务器接收到watch命令后,将客户端加入到监视列表中,以便在键被修改时通知客户端。
  3. 当有其他客户端修改了被监视的键时,Redis服务器会通知所有监视该键的客户端。
  4. 当客户端执行事务时,Redis会检查被监视的键是否发生了变化。如果发生了变化,Redis将中断事务并返回错误。
  5. 如果被监视的键没有发生变化,事务将继续执行。

总结起来,watch命令的实现原理是在Redis服务器中维护一个监视列表,并在事务执行之前对被监视的键进行监视。当键发生变化时,通知事务中的客户端并中断事务的执行。这样可以确保在事务执行期间被监视的键没有被其他客户端修改。

补充

  • watch 的实现,类似于一个 "乐观锁"。而乐观锁,不是某个具体的锁,而是指某一类锁的特性:加锁之前,就会有一个心里预期,预期接下来锁冲突的概论比较低
  • redis 的 watch 就相当于基于 "版本号" 这样的机制,实现 "乐观锁"。
  • 当执行 watch key 的时候,就会给 key 安排一个 版本号,版本号可以理解成一个"整数",每次在修改 key 的时候,版本号都会 "变大" (这个变大是没有规律的,不是每次都增长1),然后在执行 事务 的时候,就会做出判定,判断当前这个 key 的版本号和最初 watch 的时候,记录的版本号是否一致
    • 如果一致,说明当前 key 在事务开启到最终执行这个过程中,没有别的客户端修改,才能真正的执行事务.
    • 如果不一致,就说明 key 在其他客户端修改过了,因此就直接丢弃事务中的所有操作,最后返回 nil.
相关推荐
Arbori_262151 分钟前
找回mysql root 密码
数据库·mysql
zlpzlpzyd1 分钟前
spring boot 4.1发布
java·数据库·spring boot
无籽西瓜a2 分钟前
Plan-and-Execute 里的 DAG 是怎么工作的
java·后端·ai·agent·dag
石一峰6992 分钟前
SQLite 与 db_manager 集成关键概念详解
jvm·数据库·sqlite
ch.ju2 分钟前
Java Programming Chapter 4——The difference between overloading and overwriting.
java·开发语言
pigs20183 分钟前
mysql8.0 access denied for user root localhost account is locked
数据库·adb
我命由我123454 分钟前
Android 开发问题:View 的 getWidth、getHeight 方法返回的值都为 0
android·java·java-ee·android studio·android jetpack·android-studio·android runtime
满怀冰雪4 分钟前
第12篇-二分答案法-当答案不好求时如何反向搜索
java·算法
我登哥MVP6 分钟前
SpringCloud 核心组件解析:服务网关
java·spring boot·后端·spring·spring cloud·java-ee·maven
阿里云瑶池数据库6 分钟前
从开源插件到生产级引擎:PolarDB PostgreSQL的向量能力新范式
数据库·阿里云·postgresql