- 官网地址:https://redis.io/docs/latest/commands/?group=transactions
- Redis 事务可以一次执行多个命令, 并且带有以下三个重要的保证:
- 批量操作在发送 EXEC 命令前被放入队列缓存。
- 收到 EXEC 命令后进入事务执行,事务中任意命令执行失败,其余的命令依然被执行。
- 在事务执行过程,其他客户端提交的命令请求不会插入到事务执行命令序列中。
- 一个事务从开始到执行会经历以下三个阶段:
- 在分片集群中,事务要注意什么:
- 所有事务命令必须作用在同一个分片上:由于Redis Cluster的设计,一个事务中的所有命令必须指向同一个分片上的键,这是因为事务需要保持操作的原子性,而跨越多个分片的事务无法保证这一点。
- 错误处理:如果在事务中的某个命令执行时出现了转向(redirection),比如因为命令中的键不在当前分片上,那么整个事务会失败,并且已经执行的部分命令不会被回滚。这与单机Redis事务中如果命令执行出错可以回滚不同。
- 因此,如果你的事务涉及到多个分片上的键,那么你不能在一个事务中执行这样的操作。你需要手动确保事务中的所有命令都只针对单个分片上的键,或者将涉及多个分片的事务拆分为多个小的事务,每个事务操作一个分片,并且需要应用层逻辑来处理可能的一致性问题。
- 简而言之,Redis Cluster中的事务不支持跨分片操作,每条语句在一个事务中应当选择相同的分片。
- 单个 Redis 命令的执行是原子性的,但 Redis 没有在事务上增加任何维持原子性的机制,所以 Redis 事务的执行并不是原子性的。
- 事务可以理解为一个打包的批量执行脚本,但批量指令并非原子化的操作,中间某条指令的失败不会导致前面已做指令的回滚,也不会造成后续的指令不做。
MULTI#
- 标记事务块的开始。后续命令将排队等待使用EXEC进行原子执行。
- 语法:
EXEC#
- 执行所有事务块内的命令。
- 语法:
DISCARD#
- 取消事务,放弃执行事务块内的所有命令。
- 语法:
WATCH#
- 监视一个(或多个) key ,如果在事务执行之前这个(或这些) key 被其他命令所改动,那么事务将被打断。
- 语法:
UNWATCH#
- 取消 WATCH 命令对所有 key 的监视。
- 语法:
- 如果在 set b bbb 处失败,set a 已成功不会回滚,set c 还会继续执行。
$ multi
OK
$ set a aaa
QUEUED
$ set b bbb
QUEUED
$ set c ccc
QUEUED
$ exec