设为首页 收藏本站
查看: 936|回复: 0

[经验分享] 05_Redis_事务

[复制链接]

尚未签到

发表于 2016-12-17 11:16:47 | 显示全部楼层 |阅读模式
1.redis事务的概念

redis事务可以一次性执行多个命令,有两个重要的特性:


  • 事务是一个单独的隔离操作:事务中的所有命令都会序列化、按顺序地执行。事务在执行的过程中,不会被其他客户端发送来的命令请求所打断
  • 事务是一个原子操作:事务中的命令要么全部被执行,要么全部都不执行。



2.redis事务的用法
  redis实现事务控制有5个命令。这5个命令是事务的基础。

A.discard:取消事务,放弃执行事务块内的所有命令。
B.exec:执行所有事务块内的命令。
C.multi:标记一个事务块的开始。
D.unwatch:取消 WATCH 命令对所有 key 的监视。
E.watch:监视一个(或多个) key ,如果在事务执行之前这个(或这些) key 被其他命令所改动,那么事务将被打断。


3.redis事务样例:
  实例一:下面是一个最简单的事务方式

redis 127.0.0.1:6379> multi   //开启事务
OK
redis 127.0.0.1:6379> incr a  //事务中的命令
QUEUED
redis 127.0.0.1:6379> incr b
QUEUED
redis 127.0.0.1:6379> incr a
QUEUED
redis 127.0.0.1:6379> exec  //执行事务
1) (integer) 1  //返回的结果
2) (integer) 1
3) (integer) 2
redis 127.0.0.1:6379>
  说明:当客户端处于事务状态时, 所有传入的命令都会返回一个内容为 QUEUED 的状态回复(status reply), 这些被入队的命令将在 EXEC 命令被调用时执行。这些命令在客户端中以队列的形式排好队。
  实例二:开启两个客户端,在两个事务中同时访问一个变量

redis 127.0.0.1:6379> multi
OK
redis 127.0.0.1:6379> incr a
QUEUED
redis 127.0.0.1:6379> incr b
QUEUED
redis 127.0.0.1:6379> exec
1) (integer) 4
2) (integer) 3
redis 127.0.0.1:6379>

redis 127.0.0.1:6379> multi
OK
redis 127.0.0.1:6379> incr a
QUEUED
redis 127.0.0.1:6379> incr b
QUEUED
redis 127.0.0.1:6379> exec
1) (integer) 3
2) (integer) 2
redis 127.0.0.1:6379>
  说明:事务2优先与实务1,但是两个事务相互没有影响。这说明,我们开启事务后,所有要执行的命令都是在客户端的队列中。只有提交时,才在服务器端一次性,有顺序的执行。

4.redis事务中的错误


  • 事务在执行 EXEC 之前,入队的命令可能会出错。比如说,命令可能会产生语法错误(参数数量错误,参数名错误,等等),或者其他更严重的错误,比如内存不足(如果服务器使用 maxmemory 设置了最大内存限制的话)。
  • 命令可能在 EXEC 调用之后失败。举个例子,事务中的命令可能处理了错误类型的键,比如将列表命令用在了字符串键上面,诸如此类。
  说明:对于exec之前的错误,服务器会对命令入队失败的情况进行记录,并在客户端调用 EXEC 命令时,拒绝执行并自动放弃这个事务。
  在 EXEC 命令执行之后所产生的错误,并没有对它们进行特别处理:即使事务中有某个/某些命令在执行时产生了错误,事务中的其他命令仍然会继续执行
  下面举两个例子:

redis 127.0.0.1:6379> get a  //首先查看a的值:4
"4"
redis 127.0.0.1:6379> multi  //开启事务
OK
redis 127.0.0.1:6379> incr a  //将a递增1
QUEUED
redis 127.0.0.1:6379> incr c i k  //错误的语法,在exec之前的错误
(error) ERR wrong number of arguments for 'incr' command
redis 127.0.0.1:6379> exec  //提交事务
(error) EXECABORT Transaction discarded because of previous errors.
redis 127.0.0.1:6379> get a  //继续查看a的值:4
"4"   //结论说明,事务没有被执行
redis 127.0.0.1:6379>

redis 127.0.0.1:6379> multi  //开启事务
OK
redis 127.0.0.1:6379> set aa abc  //设置aa的值为:abc
QUEUED
redis 127.0.0.1:6379> lpop aa  //没有语法错误
QUEUED
redis 127.0.0.1:6379> exec  //执行事务
1) OK
2) (error) ERR Operation against a key holding the wrong kind of value
redis 127.0.0.1:6379> get aa  //aa的值仍然存在
"abc"  //结果说明,exec之后的错误,redis是不作处理的,即:没有回滚事务
redis 127.0.0.1:6379>
 5.redis为什么没有回滚事务
  在redis官方文档中描述两点:


  • Redis 命令只会因为错误的语法而失败(并且这些问题不能在入队时发现),或是命令用在了错误类型的键上面:这也就是说,从实用性的角度来说,失败的命令是由编程错误造成的,而这些错误应该在开发的过程中被发现,而不应该出现在生产环境中。
  • 因为不需要对回滚进行支持,所以 Redis 的内部可以保持简单且快速。

6.redis放弃事务

redis 127.0.0.1:6379> set aa hadoop
OK
redis 127.0.0.1:6379> get aa
"hadoop"
redis 127.0.0.1:6379> multi
OK
redis 127.0.0.1:6379> set aa hive
QUEUED
redis 127.0.0.1:6379> DISCARD
OK
redis 127.0.0.1:6379> get aa
"hadoop"
redis 127.0.0.1:6379>
 7.锁watch
  WATCH 命令可以为 Redis 事务提供 check-and-set (CAS)行为。被 WATCH 的键会被监视,并会发觉这些键是否被改动过了。 如果有至少一个被监视的键在 EXEC 执行之前被修改了, 那么整个事务都会被取消, EXEC 返回空多条批量回复(null multi-bulk reply)来表示事务已经失败。

//客户端1
redis 127.0.0.1:6379> get aa  //首先查看aa的值
"hadoop"
redis 127.0.0.1:6379> WATCH aa  //添加乐观锁
OK
redis 127.0.0.1:6379> multi  //开启事务
OK
redis 127.0.0.1:6379> set aa hive  //重新设置aa的值
QUEUED
redis 127.0.0.1:6379> exec  //在提交之前先在客户端2中重新设置aa的值
(nil)  //提交完后,返回nil
redis 127.0.0.1:6379> get aa  //重新查看,说明事务被取消了
"hbase"
//客户端2
redis 127.0.0.1:6379> set aa hbase  //在客户端2中设置aa的值为hbase
OK
redis 127.0.0.1:6379> get aa  //查看aa的值
"hbase"

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-315533-1-1.html 上篇帖子: redis 下篇帖子: redis练习
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表