前言
和MySQL一样,我们的Redis也支持事务操作,事务操作可以执行多个命令(按顺序串行化执行,执行中不会被其他命令插入)。
Redis事务
Redis事务可以一次执行多个命令(允许在一次单独的步骤中执行一组命令),并且带有以下两个重要保证:
- Redis 会将一个事务中的所有命令序列化,然后按排序执行
- 执行中不会被其他命令插入,不许出现加塞现象
常用命令
1 | 取消事务,放弃执行事务块内的所有命令 |
2 | DISCARD |
3 | |
4 | 执行所有事务内的命令 |
5 | EXEC |
6 | |
7 | 标记一个事务块的开始 |
8 | MULTI |
9 | |
10 | 取消 WATCH 命令对所有 key 的监视 |
11 | UNWATCH |
12 | |
13 | 监视一个(或多个)key,如果在事务执行之前这个(或这些)key 被其他命令所改动,那么事务将被打断 |
14 | WATCH key [key1 ...] |
事务的执行过程
一个事务从开始到执行会经历以下三个阶段:
- 开始事务
- 命令入队
- 执行事务
注意
- 批量操作在发送 EXEC 命令前被放入队列缓存。
- 收到 EXEC 命令之后,进入事务执行,事务中任意命令执行失败,其余的命令依然被执行,不支持回滚。
- 收到 EXEC 命令之后,事务中存在未知命令,事务会被整个放弃。
- 在事务执行过程,其他客户端提交的命令请求不会插入到事务执行命令序列中。
Watch 示例
我们在操作事务的时候,有可能存在对同一个key进行操作的时候,如果在事务提交之前,修改了对应的 key 就会导致一些数据错误,正确的做法就是要Watch这个值是否存在。
举个例子:
1 | 客户端1 |
2 | WATCH account:Jack |
3 | |
4 | MULTI |
5 | |
6 | SET account:Jack 100 |
7 | |
8 | INCR account:Jack 100 |
9 | |
10 | EXEC |
此时我们输入 EXEC 但是不敲下回车,切换到我们的客户端2
1 | 客户端2,我们客户端1的事务并没有提交,此时我们修改下 account:Jack |
2 | SET account:Jack 1000 |
我们先执行客户端2
的数据,我们再去 客户端1
敲击回车,我们会发现我擦事务执行失败了。哈哈哈
应用场景
一组命令必须同时都执行,或者都不执行,我们想要保证一组命令在执行的过程中不被其他命令插入。
总结
总的来说Redis的事务不是很难理解,使用多几次就知道怎么玩儿了。