Redis进阶 - 同舟共济之Redis事务

88 阅读4分钟

image

一、概述

1.1 什么是Redis事务

  Redis 事务的本质是一组命令的集合,事务可以一次执行多个命令, 事务中的所有命令都会序列化。事务在执行的过程中,会按照顺序串行化执行队列中的命令,不会被其他客户端发送来的命令请求所打断,从而保证了事物中的所有命令被原子的执行。

  和关系型数据库中的事务相比,在Redis事务中如果有某一条命令执行失败,其后的命令仍然会被继续执行。可以把事务可以理解为一个批量执行 Redis 命令的脚本,但这个操作并非原子性操作,也就是说,如果中间某条命令执行失败,并不会导致前面已执行命令的回滚,同时不会中断后续命令的执行(不包含监听 key 的情况)。

1.2 Redis事务应用

  一个事务从开始到执行会经历开始事务、命令入队、执行事务等三个阶段。Redis 事务先以 MULTI 开始一个事务, 然后将多个命令入队到事务中, 最后由 EXEC 命令触发事务, 一并执行事务中的所有命令。

# 开启事务
127.0.0.1:6379> MULTI
OK

# 命令入队成功

127.0.0.1:6379> SET book-name "Mastering C++ in 21 days"
QUEUED

127.0.0.1:6379> GET book-name
QUEUED

127.0.0.1:6379> SADD tag "C++" "Programming" "Mastering Series"
QUEUED

127.0.0.1:6379> SMEMBERS tag
QUEUED

# 批量执行命令

127.0.0.1:6379> EXEC
1) OK
2) "Mastering C++ in 21 days"
3) (integer) 3
4) 1) "Mastering Series"
   2) "C++"
   3) "Programming"

  若在事务开启之前监听了某个 key,那么您不应该在事务中尝试修改它,否则会导致事务中断。

# 开启事务之前设置key/value,并监听
127.0.0.1:6379> set www.baidu.com hello
OK
127.0.0.1:6379> WATCH www.baidu.com
OK
127.0.0.1:6379> get www.baidu.com
"hello"
# 开启事务
127.0.0.1:6379> MULTI
OK
# 更改key的value值
127.0.0.1:6379> set www.baidu.com HELLO
QUEUED
127.0.0.1:6379> GET www.baidu.com
QUEUED
# 命令执行失败
127.0.0.1:6379> EXEC
(error) EXECABORT Transaction discarded because of previous errors.
# 取消监听key
127.0.0.1:6379> UNWATCH 
OK 

1.3 Redis 事务相关命令

下表列出了 Redis 事务的相关命令:

序号命令描述
1discard取消事务,放弃执行事务块内的所有命令。
2exec执行所有事务块内的命令。
3multi标记一个事务块的开始。开启事务,Redis 会将后续的命令逐个放入队列中
4unwatch取消 watch 命令对所有 key 的监视。
5watch监视一个或多个 key ,如果在事务执行之前这个(或这些) key 被其他命令所改动,那么事务将被打断。

二、Redis事务的使用

2.1 标准的事务执行

给k1、k2分别赋值,在事务中修改k1、k2,执行事务后,查看k1、k2值都被修改。

127.0.0.1:6379> set k1 v1
OK
127.0.0.1:6379> set k2 v2
OK
127.0.0.1:6379> MULTI
OK
127.0.0.1:6379> set k1 11
QUEUED
127.0.0.1:6379> set k2 22
QUEUED
127.0.0.1:6379> EXEC
1) OK
2) OK
127.0.0.1:6379> get k1
"11"
127.0.0.1:6379> get k2
"22"

2.2 事务取消

127.0.0.1:6379> MULTI
OK
127.0.0.1:6379> set k1 33
QUEUED
127.0.0.1:6379> set k2 34
QUEUED
127.0.0.1:6379> DISCARD
OK

三、知识拓展

3.1 Redis事务执行步骤

通过上文命令执行,很显然Redis事务执行是三个阶段:

  • 开启:以MULTI开始一个事务
  • 入队:将多个命令入队到事务中,接到这些命令并不会立即执行,而是放到等待执行的事务队列里面
  • 执行:由EXEC命令触发事务

当一个客户端切换到事务状态之后, 服务器会根据这个客户端发来的不同命令执行不同的操作:

  • 如果客户端发送的命令为 EXEC 、 DISCARD 、 WATCH 、 MULTI 四个命令的其中一个, 那么服务器立即执行这个命令。
  • 与此相反, 如果客户端发送的命令是 EXEC 、 DISCARD 、 WATCH 、 MULTI 四个命令以外的其他命令, 那么服务器并不立即执行这个命令, 而是将这个命令放入一个事务队列里面, 然后向客户端返回 QUEUED 回复。

image

结语

把今天最好的表现当作明天最新的起点…...~

  投身于天地这熔炉,一个人可以被毁灭,但绝不会被打败!一旦决定了心中所想,便绝无动摇。迈向光明之路,注定荆棘丛生,自己选择的路,即使再荒谬、再艰难,跪着也要走下去!放弃,曾令人想要逃离,但绝境重生方为宿命。若结果并非所愿,那就在尘埃落定前奋力一搏!

划重点.gif