redis中事务相关的命令
watch: 监控某个或几个key的变化
multi: 接下来的命令不会立马执行,会先放入一个事务的队列中
exec: 执行事务队列中的命令
unwatch: 可以在watch执行之后 multi命令执行之前执行,效果是解除对某个key的监控
discard:可以在multi命令执行之后exec命令执行之前执行,效果是解除对某个key的监控并且移除事务队列中的命令。
案例场景说明
现在有一个交易市场,市场中的商品都存储在redis中的zset结构中 键是商品名,score是商品的价格
> ZRANGE market 0 -1 withscores1) "iphone"2) "100"3) "mac"4) "200"
这是一个顾客A要买市场中的一件商品(iphone),我们分析一下一个购买过程都发生了什么
- 从A顾客的钱包扣除100元
- 商家的钱包加100元
- iphone商品从商场移除
这个过程中“iphone”这件商品有没有在交易过程中被其他人买走是此次交易是否能成功的关键(假设iphone只有一件)。所以我们需要将上面3步放入一个事务中来执行。
事务命令演示
WATCH marketMULTI 从A顾客的钱包扣除100元 商家的钱包加100元 iphone商品从商场移除 command...EXEC
解释:
1.watch market 实现对market是否发生改变的监控。
2.MULTI 效果是将之后的命令放入一个事务队列中先不执行。
3.EXEC 对上面放入队列中的命令依次执行,这里redis可以保证队列中的命令依次执行并且其他客户端的请求要等队列中的命令执行完之后才会被处理。
4.如果在交易过程中market 发生变化(被其他客户端修改),当执行exec命令时交易(MULTI和EXEC之间的命令)不会被执行。
和mysql中实现事务的对比
- mysql中实现事务,在事务中执行对某条的数据的操作时,该条数据会被上锁。这时如果有其他事务对该条数据做处理会被阻塞,要等到持有该数据锁的事务提交或回滚后才能对该条数据进行操作。
- redis中的事务相比mysql要“儒雅”的多,他会在感知到要操作的数据已经被别人操作过后主动放弃。
- redis这样做一方面是要采用无锁的方案,提高性能。另一方面也是维持设计的简单(就像redis的单线程模型一样)
顺便说说redis的线程模型(单线程模型是怎么回事,怎么做到单线程还很快的,文件事件处理器原理)
这边博客总结的挺好