1. Redis事务的定义
Redis中的事务是一个单独的隔离操作:事务中的所有命令都会序列化,按顺序执行;事务在执行的过程中不会被其他客户端发送来的命令请求打断
Redis事务的主要作用就是串联多个命令,防止别的命令插队
2. 基本命令
2.1 Multi
multi命令开启事务,将后续的命令放入命令队列中,但不执行
2.2 Exec
2.3 Discard
discard命令用来放弃组队
可以发现,在执行了discard命令之后,系统退出了TX模式(事务模式)
2.4 Watch
在执行multi命令之前可以使用watch命令监视一个或者多个key,如果在事务执行之前,被监视的key被其他命令修改,那么事务执行将被打断
观察上述命令,先设置了一个balance,在multi执行之前对这个key进行监视,但另一个客户端在事务执行之前对balance进行了+1操作,即改变了balance的值
可以发现,当事务使用exec命令进行执行时,返回了nil,相当于java中的null,查看数据库中的值,只有balance,k1和k2并没有加入到redis中,事务执行是失败的
可以使用unwatch命令解除对所有key的监视
如果在执行WATCH命令之后,EXEC命令或DISCARD命令先被执行了的话,那么就不需要再执行UNWATCH了。
3. 事务的错误处理
3.1 情况1:组队过程中报错
在multi之后,如果加入命令队列的命令出现了语法错误(编译不通过),执行时,命令队列中的所有命令都不会被执行
可以看到 set k3这条命令本身语法有问题,在组队过程中就出现了报错,之后执行exec命令的时候,系统提示:事务因为之前的错误被打断,也就是说multi之后的命令组队被取消了,执行之后,数据库中仍然是空的
3.2 情况2:执行阶段出错
在multi之后,加入命令队列中的命令本身语法没有错误,但执行过程中出现了错误,比如incr k1,而k1所对应的值是一个字符串,那么只有这个命令不会被执行,其他命令都会执行,事务不会回滚
可以看到第三条命令incr k1对一个字符串进行+1操作,但这条命令本身是没有语法问题的,所以不会打断组队
在执行的时候,只有第三条命令执行时报错,但并不影响其他命令的执行
4. Redis事务的特性
经过上面的描述可以看出,Redis中的事务与MySQL中的事务差别还是很大的,Redis中的事务并不支持传统的ACID属性,并且Redis中的事务有三个特性
- 单独的隔离操作
事务中的所有命令都会序列化,按照顺序执行,事务在执行过程中不会被其他客户端发送来的命令打断
- 没有隔离级别的概念
队列中的命令在没有提交之前都不会被实际执行
- 不保证原子性
事务执行过程中,如果有一条命令执行失败,并不会影响其他命令的执行,没有回滚操作