Redis(十一)——Redis 的基本事务操作

本文详细介绍了Redis中的事务机制,包括事务的原子性、执行过程和异常情况。Redis事务不具备ACID特性,而是批量执行命令。在事务执行中,即使出现错误,命令也会尝试全部执行。同时,文章还讲解了如何使用WATCH进行事务监控,确保数据一致性。

Redis(十一)——Redis 的基本事务操作

1、事务概述

事务的本质

单个 Redis 命令的执行是原子性的,但 Redis 没有在事务上增加任何维持原子性的机制,所以 Redis 事务的执行并不是原子性的。

事务可以理解为一个打包的批量执行脚本,但批量指令并非原子化的操作,中间某条指令的失败不会导致前面已做指令的回滚,也不会造成后续的指令不做。

总结说:redis事务就是一次性、顺序性、排他性的执行一个队列中的一系列命令。

事务执行过程

Redis提供的事务是将多个命令打包,然后一次性、按照先进先出的顺序(FIFO)有序的执行。在执行过程中不会被打断(在事务执行过程,其他客户端提交的命令请求不会插入到事务执行命令序列中),当事务队列中的所有命令都被执行(无论成功还是失败)完毕之后,事务才会结束。

先以 MULTI 开始一个事务, 然后将多个命令入队到事务中, 最后由 EXEC 命令触发事务, 一并执行事务中的所有命令:

  1. 开启事务(MULTI)
  2. 命令入队
  3. 执行事务(EXEC)

redis 事务命令

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

序号命令及描述
1DISCARD 取消事务,放弃执行事务块内的所有命令。
2EXEC 执行所有事务块内的命令。
3MULTI 标记一个事务块的开始。
4UNWATCH 取消 WATCH 命令对所有 key 的监视。
5WATCH key key …\ 监视一个(或多个) key ,如果在事务执行之前这个(或这些) key 被其他命令所改动,那么事务将被打断。

2、执行事务

正常执行事务

127.0.0.1:6379> MULTI  #开启事务
OK
127.0.0.1:6379> set k1 v1   #命令入队
QUEUED
127.0.0.1:6379> set k2 v2 
QUEUED
127.0.0.1:6379> get k1
QUEUED
127.0.0.1:6379> get k2
QUEUED
127.0.0.1:6379> set k3 v3
QUEUED
127.0.0.1:6379> EXEC  #执行事务,再想执行事务需要重新开启
1) OK
2) OK
3) "v1"
4) "v2"
5) OK

所有的命令在事物中并没有直接被执行,只有发起执行命令(EXEC)的时候才会被执行。

放弃执行事务

DISCARD命令用于取消事务,放弃执行事务块内的所有命令。

127.0.0.1:6379> MULTI
OK
127.0.0.1:6379> set k1 v1
QUEUED
127.0.0.1:6379> set k2 v2
QUEUED
127.0.0.1:6379> DISCARD
OK

3、事务异常

编译型异常

编译型异常(语法错误),编译不能通过,事务中所有的命令都不会执行。

127.0.0.1:6379> MULTI
OK
127.0.0.1:6379> set k1 v1
QUEUED
127.0.0.1:6379> set k2 v2
QUEUED
127.0.0.1:6379> getset k3 v33
QUEUED
127.0.0.1:6379> getset k2   #错误的命令语法
(error) ERR wrong number of arguments for 'getset' command
127.0.0.1:6379> set k4 v4
QUEUED
127.0.0.1:6379> EXEC
(error) EXECABORT Transaction discarded because of previous errors.
127.0.0.1:6379> get k1
(nil)

运行时异常

运行时异常就是命令逻辑错误,但编译时可以通过

运行时异常事务中的逻辑错误命令不会被执行,其他命令正常执行

127.0.0.1:6379> MULTI
OK
127.0.0.1:6379> set k1 v1
QUEUED
127.0.0.1:6379> incr k1  #命令逻辑错误
QUEUED
127.0.0.1:6379> set k2 v2
QUEUED
127.0.0.1:6379> set k3 v3
QUEUED
127.0.0.1:6379> EXEC  #执行事务
1) OK
2) (error) ERR value is not an integer or out of range #运行时异常事务中的逻辑错误命令不会被执行,其他命令正常执行
3) OK
4) OK
127.0.0.1:6379> mget k1 k2 k3
1) "v1"
2) "v2"
3) "v3"

4、监视事务

Redis Watch 命令用于监视一个(或多个) key ,如果在事务执行之前这个(或这些) key 被其他命令所改动,那么事务将被打断。

正常执行事务并监控

127.0.0.1:6379> set money 100  #模拟账户余额
OK
127.0.0.1:6379> set out 0  #模拟支出金额
OK
127.0.0.1:6379> watch money  #监控money
OK
127.0.0.1:6379> MULTI
OK
127.0.0.1:6379> DECRBY money 20  #账户余额减少20
QUEUED
127.0.0.1:6379> INCRBY out 20  #支出金额变为20
QUEUED
127.0.0.1:6379> EXEC  #执行事务,事务正常执行
1) (integer) 80
2) (integer) 20

模拟事务执行前key被改动

1、监控money,在事务队列中放入指令,先不执行:

127.0.0.1:6379> watch money
OK
127.0.0.1:6379> MULTI
OK
127.0.0.1:6379> DECRBY money 10
QUEUED
127.0.0.1:6379> INCRBY out 10
QUEUED

2、开启一个redis 客户端,修改money 这个key的值:

127.0.0.1:6379> get money
"80"
127.0.0.1:6379> set money 1000
OK
127.0.0.1:6379> get money
"1000"

3、执行事务,事务执行失败:

127.0.0.1:6379> watch money
OK
127.0.0.1:6379> MULTI
OK
127.0.0.1:6379> DECRBY money 10
QUEUED
127.0.0.1:6379> INCRBY out 10
QUEUED
127.0.0.1:6379> EXEC
(nil)

watch指令类似于乐观锁,在事务提交时,如果watch监控的多个KEY中任何KEY的值已经被其他客户端更改,则使用EXEC执行事务时,事务队列将不会被执行,同时返回Nullmulti-bulk应答以通知调用者事务执行失败。

unwatch

Unwatch 命令用于取消 WATCH 命令对所有 key 的监视。

127.0.0.1:6379> watch money
OK
127.0.0.1:6379> unwatch
OK
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

万里顾—程

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值