文章目录
- 一、前言
- 二、Redis事务特性
- 三、事务命令基本使用
- 3.1 事务的四条命令
- 3.2 转账(开启事务并执行事务)
- 3.3 事务的取消和watch
- 四、事务发生异常
- 五、尾声
一、前言
引入Redis事务的现实需求:redis 的单个命令都是原子,比如set get,但是多个redis命令如何做到原子性呢?
答案是两种实现方式:要么是Redis事务,要么是Lua脚本。
二、Redis事务特性
Redis事务特性
1、按进入队列的顺序执行,先进入先执行
2、不会受到其他客户端的请求的影响
3、事务不能嵌套,多个multi命令效果一样
三、事务命令基本使用
3.1 事务的四条命令
事务命令:
multi:开启事务,multi表示多条,就是开启事务的意思
exec:执行事务
discard:取消事务/回滚事务
watch:监视key,如果被监视的key在exec之前被修改,事务会取消(凡是进入到事务里面就被watch了,只有修改,事务队列里这个就不能执行成功)
watch 命令的底层原理类似 cas 乐观锁(compare and set),为什么是乐观锁呢?其实还是为了保证 redis 的速度
3.2 转账(开启事务并执行事务)
set tom 1000
set mic 1000
multi
decrby tom 100
incrby mic 100
exec
3.3 事务的取消和watch
事务的取消和watch
discard:取消事务
watch:监视key,如果被监视的key在exec之前被修改,事务会取消(凡是进入到事务里面就被watch了,只有修改,事务队列里这个就不能执行成功)
watch 命令的底层原理类似 cas 乐观锁(compare and set),为什么是乐观锁呢?其实还是为了保证 redis 的速度
四、事务发生异常
事务发生异常包括两种:执行事务之前 + 执行事务之后
如果执行exec事务之前出现错误,可以回滚
如果执行exec事务之后出现错误,不可以回滚
对于执行exec事务之后出现错误,Redis的设计不可以回滚,这样设计的理由是:
(1) 一般来说,执行exec事务之后发生的都是语法错误,这种错误如果已经在测试环境中执行了,在生产环境中不会犯这样的错误;
(2) 如果向 mysql 一样,提供一个 undo log 日志,会对redis速度产生影响。
Redis 为了性能考虑,不做 undolog 日志,就无法回滚执行 exec事务 之后的错误,这也是 Redis 事务的局限性,所以开发中解决多个redis命令的原子性问题,基本都会才有 lua脚本 实现,而不是 Redis 事务。
五、尾声
Redis事务,完成了。