Redis学习笔记 ——(9)事务

本文详细介绍了Redis的事务机制,包括事务的非原子性、MULTI/EXEC/DISCARD/WATCH指令的使用,以及事务错误处理。通过WATCH实现乐观锁,确保数据一致性。在Redis中,事务主要保证批量命令的顺序执行,但不提供回滚功能。当AOF持久化开启时,事务执行的完整性依赖于redis-check-aof工具进行修复。
摘要由CSDN通过智能技术生成

Redis学习笔记 ——(9)事务

事务是指一个完整的动作,要么全部执行,要么什么也没有做。

Redis 事务不是严格意义上的事务,只是用于帮助用户在一个步骤中执行多个命令。单个 Redis 命令的执行是原子性的,但 Redis 没有在事务上增加任何维持原子性的机制,所以 Redis 事务的执行并不是原子性的。

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

Redis 事务可以一次执行多个命令, 并且带有以下三个重要的保证:

  1. 批量操作在发送 EXEC 命令前被放入队列缓存。
  2. 收到 EXEC 命令后进入事务执行,事务中任意命令执行失败,其余的命令依然被执行。
  3. 在事务执行过程,其他客户端提交的命令请求不会插入到事务执行命令序列中。

事务执行分为三个阶段:

  1. 开始事务
  2. 命令入队
  3. 执行事务
关键指令

Redis通过几个关键的失灵来实现事务

  • MULTI
    组装事务
  • EXEC
    执行事务
  • DISCARD
    取消事务
  • WATCH
    监听一些key,一旦有key在事务执行前发生变化,就取消事务的执行。
  • UNWATCH
    取消WATCH命令对所有key的监听
例子
//事务组装开始
127.0.0.1:6379> MULTI
OK
//命令入队
127.0.0.1:6379(TX)> SET cityName "beijing"
QUEUED
//命令入队
127.0.0.1:6379(TX)> GET cityName
QUEUED
//命令入队
127.0.0.1:6379(TX)> SET userName "gzy"
QUEUED
//命令入队
127.0.0.1:6379(TX)> GET userName
QUEUED
//命令入队
127.0.0.1:6379(TX)> SADD lis 1 2 3 4
QUEUED
//命令入队
127.0.0.1:6379(TX)> smembers lis
QUEUED
//命令执行,查看执行结果
127.0.0.1:6379(TX)> EXEC
1) OK
2) "beijing"
3) OK
4) "gzy"
5) (integer) 4
6) 1) "1"
   2) "2"
   3) "3"
   4) "4"

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

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

对于事务的执行来说,如果 redis 开启了 AOF 持久化的话,那么一旦事务被成功执行,事务中的命令就会通过 write 命令一次性写到磁盘中去,如果在向磁盘中写的过程中恰好出现断电、硬件故障等问题,那么就可能出现只有部分命令进行了 AOF 持久化,这时 AOF 文件就会出现不完整的情况,这时,我们可以使用 redis-check-aof 工具来修复这一问题,这个工具会将 AOF 文件中不完整的信息移除,确保 AOF 文件完整可用。

事务错误

有关事务,大家经常会遇到的是两类错误:

  1. 调用 EXEC 之前的错误

调用 EXEC 之前的错误,有可能是由于语法有误导致的,也可能时由于内存不足导致的。只要出现某个命令无法成功写入缓冲队列的情况,redis 都会进行记录,在客户端调用 EXEC 时,redis 会拒绝执行这一事务。

可以看下面的例子:

127.0.0.1:6379> multi
OK
127.0.0.1:6379(TX)> ls
(error) ERR unknown command 'ls', with args beginning with:
127.0.0.1:6379(TX)> jhsl
(error) ERR unknown command 'jhsl', with args beginning with:
127.0.0.1:6379(TX)> exec
(error) EXECABORT Transaction discarded because of previous errors.

由于ls 和jhsl为redis不能是被的错误命令,因此exec执行的时候会直接报错。
2. 调用 EXEC 之后的错误

对于调用 EXEC 之后的错误,redis 则采取了完全不同的策略,即 redis 不会理睬这些错误,而是继续向下执行事务中的其他命令。这是因为,对于应用层面的错误,并不是 redis 自身需要考虑和处理的问题,所以一个事务中如果某一条命令执行失败,并不会影响接下来的其他命令的执行。

可以看下面的例子:

127.0.0.1:6379> multi
OK
127.0.0.1:6379(TX)> set name gzy
QUEUED
//name不是一个集合,下面这个命令会执行失败
127.0.0.1:6379(TX)> sadd name zy
QUEUED
127.0.0.1:6379(TX)> exec
1) OK
2) (error) WRONGTYPE Operation against a key holding the wrong kind of value
WATCH 实现乐观锁

WATCH 本身的作用是监视 key 是否被改动过,而且支持同时监视多个 key,只要还没真正触发事务,WATCH 都会尽职尽责的监视,一旦发现某个 key 被修改了,在执行 EXEC 时就会返回 nil,表示事务无法触发。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值