Redis 事务指令原理解析

138 阅读2分钟

Redis事务是一个单独的隔离操作:事务中的所有命令都会序列化、按顺序地执行。事务在执行的过程中,不会被其他客户端发送来的命令请求所打断。

Redis事务的主要作用就是 串联多个命令 防止别的命令插队。

1. 事务相关指令(Multi、Exec、Discard

从输入Multi命令开始,输入的命令都会依次进入命令队列中,但不会执行,直到输入Exec后,Redis会将之前的命令队列中的命令依次执行。

组队的过程中可以通过Discard来放弃组队。

1.1 测试Multi+Exec指令

1.1.1 组队成功 提交成功

image.png

image.png

1.1.2 组队成功 提交部分失败部分成功

image.png

image.png

1.1.2 组队失败 提交失败

image.png

image.png

1.1.3 Redis事务不支持事务回滚

多数事务失败是由语法错误或者数据结构类型错误导致的,语法错误说明在命令入队前就进行检测的,而类型错误是在执行时检测的, Redis为提升性能而采用这种简单的事务 ,这是不同于关系型数据库的,特别要注意区分。

1.2 测试Multi+Discard指令

image.png

2. 事务打断相关指令(watch、unwatch

2.1 watch 指令

redis事务是不支持回滚的,如果特殊情况强制需要回滚,可在Multi之前使用watch命令了。

watch指令的作用是监控一个值是否发生变化,如果没发生改变,它会执行事务队列中的命令,提交事务;如果发生变化,将不会执行事务中的任何命令,同时事务回滚。最后无论是否回滚,Redis都会取消执行事务前的WATCH命令。

image.png

multi未执行之前,即使watch监控a的值,也无法打断;当multi执行后,一系列的对a和b的指令都会执行失败,从而达到回滚的效果。

image.png

2.2 unwatch 指令

unwatch命令是取消监控,取消watch监控a的值并打断事务的行为。

image.png

3. Redis事务的三特性

  •  单独的隔离操作

 事务中的所有命令都会序列化、按顺序地执行。事务在执行的过程中,不会被其他客户端发送来的命令请求所打断。

  • 没有隔离级别的概念

 队列中的命令没有提交之前都不会实际被执行,因为事务提交前任何指令都不会被实际执行

  • 不保证原子性

事务中如果有一条命令执行失败,其后的命令仍然会被执行,没有回滚