最新消息:

理解 Redis 事务之 watch 命令

Redis 323浏览 0评论

事务最大的一个特征就是原子性,保证了对数据的原子性操作。

Mysql 中实现事务一般步骤是:启动事务,执行 select …… for update,对要操作的数据行上锁,也就是行级锁。此时,如果并发的进程处理到处于锁定状态的数据行时,首先判定该行是否被其他进程上读锁,如果是,则一定先等待锁释放,再执行操作,这种对任何操作“都不信任”的锁,即是悲观锁。

在 redis 中实现事务有多种方法,此处讲解用 watch 监控某个 key 是否被其他进程修改,watch 乐观锁的实现方案,也就是说,先假定所有的而进程之间的数据操作没有任何交集,执行一系列的操作,在最后提交的时候,如果发现被监控的key 已经被其他的进程修改了,则提交时返回 false。

PHP 中使用 redis 的watch 实现示例如下:

$redis = new \Redis();
$redis->connect('127.0.0.1', 6379);
//将被监控的key
$watchKey = 'watchkey'; 
//监控 key, 必须在事务启用之前执行监控,
//因为在执行 multi 命令之后,所有的命令将会进入到一个 redis 队列,然后保证这些命令可以不被其他程序打扰的情况下依次执行,
//这也就是redis的事务原子性操作的方法
$redis->watch($watchKey); 
//启用事务
$redis->multi();
//睡眠提供同时操作机会
sleep(3);
//修改被监控的键值,incr 是redis 的计数器,原子性操作,执行一次增加1
//这里计数增加两次
$redis->incr($watchKey);
$redis->incr($watchKey);
//在事务内的所有操作都将返回 redis 连接对象,只有在执行 exec 命令后返回结果中,所有的返回数据将反倒数组中返回
$redis->get($watchKey);
//执行事务,如果事务执行失败则返回false, 正确则返回事务中的所有返回结果
$result = $redis->exec();
var_dump($result);

执行结果如下图:

image.png

可以发现,只要第一个事务执行成功,而后面两个都是失败的。

理论上,如果三次都执行成功,那么watchkey的值的增加量应该是 6,redis-cli 中我们查看 watchkey 的值的变化:

image.png

结果发现,watchkey 的值也仅仅只增加了 2,再一次证实,上述三次触发执行中,只有第一次事务是执行成功的。

转载请注明:微刻 blog.wecot.cn » 理解 Redis 事务之 watch 命令

发表我的评论
取消评论
表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址