大数据求索(15): Redis事务详解
大数据求索(15): Redis事务详解
一、什么是事务
- 事务是一个单独的隔离操作:事务中的所有命令都会序列化、按顺序执行。事务在执行的过程中,不会被其他客户端发送来的命令请求打断。
- 事务是一个原子操作:事务中的命令要么全部被执行,要么全部都不执行。
二、Redis中的事务
2.1 常用命令
MULTI、EXEC、DISCARD和WATCH是Redis事务相关的命令。
- MULTI:标记一个事务块的开始
- EXEC:执行所有事务块内的命令
- DISCARD:取消事务,放弃执行事务块内的所有命令
- WATCH:监视一个或多个key,如果在事务执行之前这些key被其他命令所改动,那么事务将被打断。
- UNWATCH:取消watch命令对所有key的监视
2.2 使用实例
正常执行
放弃事务
全体连坐
即,一个显式错误,全部受牵连,都不执行
冤头债主
即对的执行,错的抛出错误
三、Watch用法
3.1 乐观锁和悲观锁
悲观锁(Pessimistic Lock), 顾名思义,就是很悲观,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会block直到它拿到锁。
传统的关系型数据库里边就用到了很多这种锁机制,比如行锁,表锁等,读锁,写锁等,都是在做操作之前先上锁。
乐观锁(Optimistic Lock), 顾名思义,就是很乐观,每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据,可以使用版本号等机制。
乐观锁适用于多读
的应用类型,这样可以提高吞吐量。
在redis里,乐观锁策略:提交版本必须 大于
记录当前版本才能执行更新。
3.2 watch命令
Watch指令,类似乐观锁,事务提交时,如果Key的值已被别的客户端改变,
比如某个list已被别的客户端push/pop过了,整个事务队列都不会被执行。
通过WATCH命令在事务执行之前监控了多个Keys,倘若在WATCH之后有任何Key的值发生了变化,EXEC命令执行的事务都将被放弃,同时返回Nullmulti-bulk应答以通知调用者事务执行失败。如下图所示
在第一张图执行事务期间,第二张图表示新建了另一个连接客户端,并对balance进行了修改。此时,第一张图中watch
了balance这个key,监控到了变化,所以整个事务没有正确执行,返回了一个nil
。
注意:
一旦exec了,watch加的监控锁都会自动取消。
当然,也可以使用unwatch手动取消。这里就不演示了。