您的位置:首页 > 数据库 > Redis

Redis的事务机制和订阅发布

2017-11-15 20:03 375 查看
事务
Redis事务提供了一种“将多个命令打包,然后一次性、按顺序地执行”的机制。
一个事务从开始到执行会经历以下三个阶段:
1.
开始事务。
2.
命令入队。
3.
执行事务。
 
开始事务(MULTI):
该命令唯一干的事情就是打开事务。
命令入队:
事务状态下,服务器收到客户端的命令时不会立即执行,而且是按顺序压到一个队列中。
执行事务(EXEC):
命令队列以先入先出的顺序按序执行,并将执行结果按顺序反馈,同时将事务状态修改为非事务。
取消事务(DISCARD)
将命令队列清空,同时将事务状态修改为非事务。
测试案例:



可以看到事务状态下执行命令只返回一个queued,标识存入了队列,但不会立即执行。
Redis的事务不是嵌套的,一个客户端一次只能打开一个事务,重复multi打开事务会返回一个error信息,但是不会影响已开启的事务。
 
WATCH
命令用于在事务开始之前监视任意数量的键:当调用 EXEC
命令执行事务时,如果任意一个被监视的键已经被其他客户端修改了,那么整个事务不再执行,直接返回失败
测试案例:



在exec之前key为name的这个数据被另一个客户端修改成了”no”,所以事务执行失败了,返回的不是命令执行结果,而是(nil)。
Watch原理:
被监控的key是在一个watched_keys字典中维护的,每多一个客户端监控,就会在key后面增加一链。例如下图key3这个key被client3、client4、client6三个客户端watch中。



对这些key执行修改命令时,会将该建挂载的client链上所有客户端上REDIS_DIRTY_CAS选项打开,而客户端再执行事务的exec命令时会先判断自己的REDIS_DIRTY_CAS是否被打开,如果被打开那么事务执行失败。
由于REDIS_DIRTY_CAS这个状态位是属于客户端的而不是属于客户端上某一个key的,所以事务执行结果只能单纯的返回成功失败,而不能返回具体是哪个key引起的失败。
事务结束时,无论成功失败,所有watched_keys中该client的链环都将被清楚。
 

订阅发布

本文把Redis的订阅与发布功能与事务放在同一篇幅一起介绍,是因为订阅与发布的数据结构与Watch的结构是一样的。
客户端通过subscribe订阅要监听的频道,有新消息通过publish推送到该频道上,消息内容就会推送给定于过该频道的客户端。
如图:



上图为比较好理解的“基于频道的订阅与发布”,redis还支持“模式的订阅与发布”,client端不再订阅具体的频道名称上,而是订阅到一个表达式,满足这个表达式的频道被推送信息时将会推送给client。
如图:



对于client123和client256来说,无论是tweet.shop.ipad还是tweet.shop.kindle被推送了信息都会收到来自频道的内容。
“基于频道的退订”用unsubscribe命令,“基于模式的退订”用punsubscribe命令。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  redis 事务