1. Redis事务的定义

Redis中的事务是一个单独的隔离操作:事务中的所有命令都会序列化,按顺序执行;事务在执行的过程中不会被其他客户端发送来的命令请求打断

Redis事务的主要作用就是串联多个命令,防止别的命令插队

2. 基本命令

2.1 Multi

multi命令开启事务,将后续的命令放入命令队列中,但不执行
multi.jpg

2.2 Exec

exec命令用来执行命令队列中的命令
exec.jpg

2.3 Discard

discard命令用来放弃组队
discard.jpg
可以发现,在执行了discard命令之后,系统退出了TX模式(事务模式)

2.4 Watch

在执行multi命令之前可以使用watch命令监视一个或者多个key,如果在事务执行之前,被监视的key被其他命令修改,那么事务执行将被打断
watch.jpg
观察上述命令,先设置了一个balance,在multi执行之前对这个key进行监视,但另一个客户端在事务执行之前对balance进行了+1操作,即改变了balance的值
执行出错.jpg
可以发现,当事务使用exec命令进行执行时,返回了nil,相当于java中的null,查看数据库中的值,只有balance,k1和k2并没有加入到redis中,事务执行是失败的

可以使用unwatch命令解除对所有key的监视
如果在执行WATCH命令之后,EXEC命令或DISCARD命令先被执行了的话,那么就不需要再执行UNWATCH了。

3. 事务的错误处理

3.1 情况1:组队过程中报错

在multi之后,如果加入命令队列的命令出现了语法错误(编译不通过),执行时,命令队列中的所有命令都不会被执行
组队出错.jpg
可以看到 set k3这条命令本身语法有问题,在组队过程中就出现了报错,之后执行exec命令的时候,系统提示:事务因为之前的错误被打断,也就是说multi之后的命令组队被取消了,执行之后,数据库中仍然是空的

3.2 情况2:执行阶段出错

在multi之后,加入命令队列中的命令本身语法没有错误,但执行过程中出现了错误,比如incr k1,而k1所对应的值是一个字符串,那么只有这个命令不会被执行,其他命令都会执行,事务不会回滚
执行出错.jpg
可以看到第三条命令incr k1对一个字符串进行+1操作,但这条命令本身是没有语法问题的,所以不会打断组队
在执行的时候,只有第三条命令执行时报错,但并不影响其他命令的执行

4. Redis事务的特性

经过上面的描述可以看出,Redis中的事务与MySQL中的事务差别还是很大的,Redis中的事务并不支持传统的ACID属性,并且Redis中的事务有三个特性

  1. 单独的隔离操作

事务中的所有命令都会序列化,按照顺序执行,事务在执行过程中不会被其他客户端发送来的命令打断

  1. 没有隔离级别的概念

队列中的命令在没有提交之前都不会被实际执行

  1. 不保证原子性

事务执行过程中,如果有一条命令执行失败,并不会影响其他命令的执行,没有回滚操作