Redis事务

本文详细解读了Redis事务的原子性特点,介绍了事务的执行流程,包括multi命令开启、命令入队和exec执行,并探讨了乐观锁机制(watch-key与unwatch)。实例演示了事务的异常处理和乐观锁在转账场景中的应用。
摘要由CSDN通过智能技术生成

事务特性

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

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

事务执行基本流程

一个事务从开始到执行会经历以下三个阶段:

  1. 开始事务。
  2. 命令入队。
  3. 执行事务。

事务常用命令

multi: 标记事务的开启
exec :执行事务
discard:取消事务,放弃执行事务块内的所有命令。
watch key :监视key,在一个事务内监视了某些key,如果在执行事务之前这个key的值有被其他命令改变,那么本次事务中对这个key的操作就会失败
unwatch:取消对所有key的监视。

事务执行

异常:

编译型异常:(入队时会提示命令错误),该事务的所有命令都不会被执行。
例子如下:事务中有一条命令入队时提示错误了,最后执行事务的时候整个事务都会执行失败。

127.0.0.1:6379> multi
OK
127.0.0.1:6379(TX)> g 1
(error) ERR unknown command `g`, with args beginning with: `1`,
127.0.0.1:6379(TX)> get name
QUEUED
127.0.0.1:6379(TX)> get age
QUEUED
127.0.0.1:6379(TX)> exec
(error) EXECABORT Transaction discarded because of previous errors.
127.0.0.1:6379>

运行时异常:(入队时没有错误,但是执行的时候会出现错误),只是出现异常的命不会被执行,其他命令依旧执行。

例子如下:可以看到命令都是成功入队,但是执行的时候会有一条命令执行失败(原因是字符串不能执行+1操作),但是不影响正确命令的执行。

127.0.0.1:6379> set name ljh
OK
127.0.0.1:6379> multi
OK
127.0.0.1:6379(TX)> set age 22
QUEUED
127.0.0.1:6379(TX)> incrby name 1
QUEUED
127.0.0.1:6379(TX)> exec
1) OK
2) (error) ERR value is not an integer or out of range
127.0.0.1:6379>

乐观锁:

Redis的watch监视器的作用其实就相当于乐观锁(乐观锁机制认为资源不会被人修改,所以默认不加锁,而是用一个version字段来标识这条数据是否被别人修改过,如:用0表示没有被修改,1表示被修改),watch就是用来监视数据有没有被修改的,在Redis事务中,如果监视的数据被修改过,那么本次事务会执行失败,需要重新监视数据,然后重新执行事务。
例:
设置账户1有100元,账户二有900元,然后监视账户1:

127.0.0.1:6379> set money1 100
OK
127.0.0.1:6379> set money2 900
OK
127.0.0.1:6379> watch money1

然后开启一个事务用于转账:账户2向账户1转账200元:(先不提交事务)

127.0.0.1:6379> multi
OK
127.0.0.1:6379(TX)> incrby money1 200
QUEUED
127.0.0.1:6379(TX)> decrby money2 200
QUEUED

开启另外一个客户端,模拟别人修改账户1的金额为1000元:

127.0.0.1:6379> set money1 1000
OK

最后提交转账事务:

127.0.0.1:6379(TX)> exec
(nil)

结果:返回nil说明事务执行失败。因为在转账事务中还没有执行就先被别人抢先修改了数据。
解决方法是:重新监视数据,再一次执行事务,直到成功为止。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值