redis 的事务

纠结了一个下午,在想到底要不要写这篇文章,理由是这篇文章写的很棒很细(文章链接地址:https://redisbook.readthedocs.io/en/latest/feature/transaction.html),以至于纠结到现在,当然好在顺藤摸瓜,发现了这个网站 -- redis 设计与实现( 链接:http://redisbook.com/ ),从源码角度分析了 redis 各种功能的实现,特此向在学习 redis 的朋友推荐下。这里从使用的角度说下 redis 事务及使用场景 。

    redis  事务

       在 redis 中开启事务用 multi 命令,事务提交用 exec  命令 ,回滚事务用 discard 命令。

127.0.0.1:6379> set wang 100
OK
127.0.0.1:6379> set zhang 900
OK
127.0.0.1:6379> mget zhang wang
1) "900"
2) "100"
127.0.0.1:6379> multi 
OK
127.0.0.1:6379> incrby wang 200
QUEUED
127.0.0.1:6379> decrby zhang 200
QUEUED
127.0.0.1:6379> 

可以看到,在开启事务后 ,后面的命令服务端会返回 QUEUED   给客户端( 前提是该命令是正确的,否则会返回错误信息 ),表示该条命令已放到要执行的事务队列中。

跟传统关系型数据库一样,在事务未提交之前,事务内所作的更改不生效

事务未提交前,在其它客户端读取到内容是事务未提交前的值

提交事务 / 回滚事务 

这里着重说下事务提交,redis 事务和传统数据库事务是有差别的,在传统关系型数据库中事务执行出错,整个事务回滚,但在redis 中,会跳过出错命令,继续往下执行直到该事务执行完毕。

正常事务操作

执行事务过程中出现错误

跳过出错命令,继续往下执行该事务直到事务执行完毕。

一般语法出错,redis 会放弃此次事务的执行( 既不会出现此类现象 ),像这种对不恰到的数据类型进行的错误操作导致的问题,应该由开发者来自行回避。

      场景

秒杀,抢票。

模拟米9 抢购场景

如果在事务提交前,有人手速比你快,抢走了最后一部mi9

而当你这边事务提交的后,

会发现,扣款成功了,但你告诉我没货了,这尼玛明显不合理嘛!!!!!

在redis 事务中,使用乐观锁,常配合watch 命令来完成事务操作。

WATCH 命令用于在事务开始之前监视任意数量的键: 当调用 EXEC 命令执行事务时, 如果任意一个被监视的键已经被其他客户端修改了, 那么整个事务不再执行, 直接返回失败。

既然有watch ,那么就有unwatch ,unwatch 是取消监视的key 。

下面再模拟一次,抢购场景

 

嗯,这次虽然没抢到,但钱款没扣,只能怪运气不好喽。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章