zoukankan      html  css  js  c++  java
  • Redis的事务

    一、相关命令
    1. MULTI
    用于标记事务块的开始。Redis会将后续的命令逐个放入队列中,然后才能使用EXEC命令原子化地执行这个命令序列。
    这个命令的运行格式如下所示:
    MULTI
    这个命令的返回值是一个简单的字符串,总是OK。
    2. EXEC
    在一个事务中执行所有先前放入队列的命令,然后恢复正常的连接状态。
    当使用WATCH命令时,只有当受监控的键没有被修改时,EXEC命令才会执行事务中的命令,这种方式利用了检查再设置(CAS)的机制。
    这个命令的运行格式如下所示:
    EXEC
    这个命令的返回值是一个数组,其中的每个元素分别是原子化事务中的每个命令的返回值。 当使用WATCH命令时,如果事务执行中止,那么EXEC命令就会返回一个Null值。
    3. DISCARD
    清除所有先前在一个事务中放入队列的命令,然后恢复正常的连接状态。
    如果使用了WATCH命令,那么DISCARD命令就会将当前连接监控的所有键取消监控。
    这个命令的运行格式如下所示:
    DISCARD
    这个命令的返回值是一个简单的字符串,总是OK。
    4. WATCH
    当某个事务需要按条件执行时,就要使用这个命令将给定的键设置为受监控的。
    这个命令的运行格式如下所示:
    WATCH key [key ...]
    这个命令的返回值是一个简单的字符串,总是OK。
    对于每个键来说,时间复杂度总是O(1)。
    5. UNWATCH
    清除所有先前为一个事务监控的键。
    如果你调用了EXEC或DISCARD命令,那么就不需要手动调用UNWATCH命令。
    这个命令的运行格式如下所示:
    UNWATCH
    这个命令的返回值是一个简单的字符串,总是OK。
    时间复杂度总是O(1)。

    二、使用方法
    使用MULTI命令便可以进入一个Redis事务。这个命令的返回值总是OK。此时,用户可以发出多个Redis命令。Redis会将这些命令放入队列,而不是执行这些命令。一旦调用EXEC命令,那么Redis就会执行事务中的所有命令。相反,调用DISCARD命令将会清除事务队列,然后退出事务。
    以下示例会原子化地递增foo键和bar键的值:


    正如从上面的会话所看到的一样,EXEC命令的返回值是一个数组,其中的每个元素都分别是事务中的每个命令的返回值,返回值的顺序和命令的发出顺序是相同的。
    当一个Redis连接正处于MULTI请求的上下文中时,通过这个连接发出的所有命令的返回值都是QUEUE字符串。当调用EXEC命令时,Redis会简单地调度执行事务队列中的命令。

    三、事务内部的错误
    在一个事务的运行期间,可能会遇到两种类型的命令错误:
    1.语法错误(显示错误):一个命令可能会在被放入队列时失败。因此,事务有可能在调用EXEC命令之前就发生错误。例如,这个命令可能会有语法错误(参数的数量错误、命令名称错误,等等),或者可能会有某些临界条件(例如:如果使用maxmemory指令,为Redis服务器配置内存限制,那么就可能会有内存溢出条件)。
    2.运行时错误(隐式错误):在调用EXEC命令之后,事务中的某个命令可能会执行失败。例如,我们对某个键执行了错误类型的操作(例如,对一个字符串(String)类型的键执行列表(List)类型的操作)。
    示例1:

    上述示例中,由于INCR命令的语法错误,Redis根本就没有将这个命令放入事务队列。因此在执行EXEC命令后,整个事务都没有被执行。

    示例2:

    上述示例中,EXEC命令的返回值是批量的字符串,包含两个元素,一个是OK代码,另一个是-ERR错误消息。客户端会根据自身的程序库,选择一种合适的方式,将错误信息提供给用户。需要注意的是,即使某个命令执行失败,事务队列中的所有其他命令仍然会执行 —— Redis不会停止执行事务中的命令。

     四、Redis不支持回滚
    如果你具备关系型数据库的知识背景,你就会发现一个事实:在事务运行期间,虽然Redis命令可能会执行失败,但是Redis仍然会执行事务中余下的其他命令,而不会执行回滚操作,你可能会觉得这种行为很奇怪。


    然而,这种行为也有其合理之处:
    只有当被调用的Redis命令有语法错误时,这条命令才会执行失败(在将这个命令放入事务队列期间,Redis能够发现此类问题),或者对某个键执行不符合其数据类型的操作:实际上,这就意味着只有程序错误才会导致Redis命令执行失败,这种错误很有可能在程序开发期间发现,一般很少在生产环境发现。
    Redis已经在系统内部进行功能简化,这样可以确保更快的运行速度,因为Redis不需要事务回滚的能力。

    五、终止事务
    DISCARD命令可以用来中止事务运行。在这种情况下,不会执行事务中的任何命令,并且会将Redis连接恢复为正常状态。示例如下所示:

    六、WATCH命令
    WATCH命令可以监控一个或多个键,一旦其中有一个键被修改(或删除),之后的事务就不会执行,监控一直持续到EXEC命令(事务中的命令是在EXEC之后才执行的,EXEC命令执行完之后被监控的键会自动被UNWATCH)

    示例1:

    上面的例子中,首先设置mykey的键值为1,然后使用WATCH命令监控mykey,随后更改mykey的值为2,然后进入事务,事务中设置mykey的值为3,然后执行EXEC运行事务中的命令,最后使用get命令查看mykey的值,发现mykey的值还是2,也就是说事务中的命令根本没有执行(因为WATCH监控mykey的过程中,mykey被修改了,所以随后的事务便会被取消)。
    注意:由于WATCH命令的作用只是当被监控的键被修改后取消之后的事务,并不能保证其他客户端不修改监控的值,所以当EXEC命令执行失败之后需要手动重新执行整个事务。
    执行EXEC命令之后会取消监控使用WATCH命令监控的键,如果不想执行事务中的命令,也可以使用UNWATCH命令来取消监控。

  • 相关阅读:
    shell 自动map和unmap 应用实例url域名【升级版】
    shell 自动map和unmap 应用实例url域名【初级版】
    cloudfoundry容器实例内部测试redis连通性
    Tsunami 跨机房大数据迁移【ubuntu】
    BOS项目05——Action层抽取重复代码(接受page,rows参数,封装到pageUtils对象中;对象转Json),批量添加数据的流程,批量删除流程(主要看前端部分),easyUI选项框(发送ajax请求从region中获取数据),JsonLib转码的原理(get方法),分页查询重复调用问题
    idea与Pycharm破解(Maven+Ubuntu:http://www.cnblogs.com/LexMoon/p/JavaMavenUbuntu.html)
    BOS项目
    前端——EasyUI基本使用
    Mavent——学Java不会Maven,怎么行archetypeCatalog=internal
    SpringMVC——高级参数绑定(数组、集合),@RequestMapper 的使用,Controller方法的三种返回值类型,异常处理器,上传图片,JSON数据交互,配置拦截器
  • 原文地址:https://www.cnblogs.com/web424/p/6904133.html
Copyright © 2011-2022 走看看