zoukankan      html  css  js  c++  java
  • Redis事务 MULTI、EXEC、Watch

    Redis事务

    redis是NOSQL数据库,所以也存务,只是在事此事务和关系型数据库的事务是有区别的。

    事务实例

    MULTI 命令

    在执行 MULTI 命令之后,此时将进入阻塞状态。当我们继续发送命令时,命令不会立即执行,而是会排队等待。直到输入 EXEC 命令执行,队列中的命令才会一一执行

    127.0.0.1:6379> MULTI
    OK
    127.0.0.1:6379> set k1 111
    QUEUED
    127.0.0.1:6379> set k2 222
    QUEUED
    127.0.0.1:6379> set k3 333
    QUEUED
    127.0.0.1:6379> set k4 444
    QUEUED
    127.0.0.1:6379> get k3
    QUEUED
    

    EXEC 命令

    127.0.0.1:6379> EXEC
    1) OK
    2) OK
    3) OK
    4) OK
    5) "333"
    

    事务异常

    1. 进入队列之前发生错误

    一般都是命令出现错误。Redis 会将进入队列失败的事件进行记录,在执行 EXEC 命令提交事务的时候,不会执行并且会放弃这一条事务。

    输入命令

    127.0.0.1:6379> multi
    OK
    127.0.0.1:6379> set name zhang
    QUEUED
    127.0.0.1:6379> set age 18
    QUEUED
    127.0.0.1:6379> set sex nan haha #故意写错
    QUEUED
    127.0.0.1:6379> set address beijing
    QUEUED
    
    

    执行结果

    127.0.0.1:6379> exec
    1) OK
    2) OK
    3) (error) ERR syntax error
    4) OK
    

    查询数据

    127.0.0.1:6379> keys *
    1) "address"
    2) "name"
    3) "age"
    127.0.0.1:6379> get name
    "zhang"
    127.0.0.1:6379> get sex
    (nil)
    
    Redis 是没有回滚操作的

    Redis 命令只会因为错误的语法而失败(并且这些问题不能在入队时发现),或是命令用在了错误类型的键上面:这也就是说,从实用性的角度来说,失败的命令是由编程错误造成的,而这些错误应该在开发的过程中被发现,而不应该出现在生产环境中。

    因为不需要对回滚进行支持,所以 Redis 的内部可以保持简单且快速

    Watch 命令

    watch 命令可以监控一个或多个键,一旦有其中一个键被修改(被删除),后面的事务就不会执行了。监控一直持续到 EXEC 命令(事务中的命令是在exec之后才执行的,所以在multi命令后可以修改watch监控的键值)

    假设我们通过watch命令在事务执行之前监控了多个Keys,倘若在watch之后有任何Key的值发生了变化,exec命令执行的事务都将被放弃,同时返回Null multi-bulk应答以通知调用者事务执行失败。

    执行 watch 命令,不执行 MULTI、exec

    这里可以看到保存到数据数据库的 name = zhang 被修改成了 name = li

    127.0.0.1:6379> set name zhang
    OK
    127.0.0.1:6379> WATCH name
    OK
    127.0.0.1:6379> set name li
    OK
    127.0.0.1:6379> get name
    "li"
    
    执行 watch 命令,通知执行 MULTI、exec

    使用 watch 监听 age ,在再执行 MULTI 命令,在执行 exec 之前 age 有任何改变,都不会执行此事务

    127.0.0.1:6379> set age 18
    OK
    127.0.0.1:6379> WATCH age
    OK
    127.0.0.1:6379> MULTI
    OK
    127.0.0.1:6379> set age 21
    QUEUED
    127.0.0.1:6379> exec
    (nil)
    127.0.0.1:6379> get age
    "18"
    127.0.0.1:6379> 
    
    

    exec 执行之后,会自动执行 UNWatch 命令,撤销监听操作

    127.0.0.1:6379> set age 18
    OK
    127.0.0.1:6379> WATCH age
    OK
    127.0.0.1:6379> MULTI
    OK
    127.0.0.1:6379> set age 21
    QUEUED
    127.0.0.1:6379> exec
    (nil)
    127.0.0.1:6379> get age
    "18"
    127.0.0.1:6379> set age 20
    OK
    127.0.0.1:6379> get age
    "20"
    
    

    UnWatch 命令

    此命令表示撤销监听

    下面的操作测试可以看到,取消监听后,exec 提交事务后,address 被修改了

    127.0.0.1:6379> set address beijing
    OK
    127.0.0.1:6379> WATCH address
    OK
    127.0.0.1:6379> MULTI
    OK
    127.0.0.1:6379> UNWATCH
    QUEUED
    127.0.0.1:6379> set address nanchang
    QUEUED
    127.0.0.1:6379> exec
    1) OK
    2) OK
    127.0.0.1:6379> get address
    "nanchang"
    
  • 相关阅读:
    【BZOJ】1671: [Usaco2005 Dec]Knights of Ni 骑士(bfs)
    【BZOJ】1689: [Usaco2005 Open] Muddy roads 泥泞的路(贪心)
    Maven使用
    上传图片
    Model、ModelMap和ModelAndView的使用详解
    Spring MVC 基于AnnotationFormatterFactory接口实现自定义的规则
    mybatis 分页插件PageHelper的简单使用
    Mybatis 自动生成mapper文件
    Tomcat部署时war和war exploded区别以及平时踩得坑
    springMVC @response 中文乱码解决
  • 原文地址:https://www.cnblogs.com/zhiwenxi/p/11863490.html
Copyright © 2011-2022 走看看