Redis 的事务就是将多个命令序列化,按顺序执行,并且它们在执行的过程中,不会被其他客户端发来的命令请求所打断。
一个事务从开始到执行会经历以下三个阶段:
- 开始事务,使用 MULTI命令。
- 命令入队,正常的操作命令。
- 执行事务, EXEC命令。
也可以在 EXEC 之前用 DISCARD 放弃这个事务。
另外需要注意的是,
- 如果入队过程中命令报错了,执行时会直接报错,所有的命令都不会执行。
- 如果入队过程中没有命令报错,而在执行过程中,某个命令执行失败,则不影响其他命令的执行。
下面练习一下 redis 处理秒杀商品的案例。
秒杀商品
代码如下:
1 | python复制代码def handle_buy_product(user): |
使用 locust 模拟高并发场景。
1 | python复制代码from locust import HttpUser, task |
可以发现会出现超卖的情况,也就是商品库存被扣到负数。
使用事务解决
我们可以使用 pipeline,watch, multi, execute 来解决。其本质上是使用了乐观锁来处理并发问题。
1 | python复制代码def handle_buy_product(user): |
实验结果可以发现,不会出现超卖问题了,但是,可以观察到,会出现很多次的秒杀失败,商品数量下降的也比较慢。
使用 lua 锁
我们可以使用 lua 锁(悲观锁)来解决上面的问题。
1 | python复制代码def handle_buy_product(user): |
本文转载自: 掘金