MULTI

MULTI:标记一个事务块的开始。
事务块内的多条命令会按照先后顺序被放进一个队列当中,最后由 EXEC 命令原子性(atomic)地执行。

可用版本:>= 1.2.0

时间复杂度:O(1)。

返回值:总是返回 OK。

  1. redis> MULTI # 标记事务开始
  2. OK
  3.  
  4. redis> INCR user_id # 多条命令按顺序入队
  5. QUEUED
  6.  
  7. redis> INCR user_id
  8. QUEUED
  9.  
  10. redis> INCR user_id
  11. QUEUED
  12.  
  13. redis> PING
  14. QUEUED
  15.  
  16. redis> EXEC # 执行
  17. ) (integer)
  18. ) (integer)
  19. ) (integer)
  20. ) PONG

EXEC

EXEC

执行所有事务块内的命令。

假如某个(或某些) key 正处于 WATCH 命令的监视之下,且事务块中有和这个(或这些) key 相关的命令,那么 EXEC 命令只在这个(或这些) key 没有被其他命令所改动的情况下执行并生效,否则该事务被打断(abort)。

可用版本:
>= 1.2.0
时间复杂度:
事务块内所有命令的时间复杂度的总和。
返回值:
事务块内所有命令的返回值,按命令执行的先后顺序排列。
当操作被打断时,返回空值 nil 。
  1. # 事务被成功执行
  2.  
  3. redis> MULTI
  4. OK
  5.  
  6. redis> INCR user_id
  7. QUEUED
  8.  
  9. redis> INCR user_id
  10. QUEUED
  11.  
  12. redis> INCR user_id
  13. QUEUED
  14.  
  15. redis> PING
  16. QUEUED
  17.  
  18. redis> EXEC
  19. ) (integer)
  20. ) (integer)
  21. ) (integer)
  22. ) PONG
  23.  
  24. # 监视 key ,且事务成功执行
  25.  
  26. redis> WATCH lock lock_times
  27. OK
  28.  
  29. redis> MULTI
  30. OK
  31.  
  32. redis> SET lock "huangz"
  33. QUEUED
  34.  
  35. redis> INCR lock_times
  36. QUEUED
  37.  
  38. redis> EXEC
  39. ) OK
  40. ) (integer)
  41.  
  42. # 监视 key ,且事务被打断
  43.  
  44. redis> WATCH lock lock_times
  45. OK
  46.  
  47. redis> MULTI
  48. OK
  49.  
  50. redis> SET lock "joe" # 就在这时,另一个客户端修改了 lock_times 的值
  51. QUEUED
  52.  
  53. redis> INCR lock_times
  54. QUEUED
  55.  
  56. redis> EXEC # 因为 lock_times 被修改, joe 的事务执行失败
  57. (nil)

DISCARD

DISCARD

取消事务,放弃执行事务块内的所有命令。

如果正在使用 WATCH 命令监视某个(或某些) key,那么取消所有监视,等同于执行命令 UNWATCH 。

可用版本:
>= 2.0.0
时间复杂度:
O(1)。
返回值:
总是返回 OK 。
  1. redis> MULTI
  2. OK
  3.  
  4. redis> PING
  5. QUEUED
  6.  
  7. redis> SET greeting "hello"
  8. QUEUED
  9.  
  10. redis> DISCARD
  11. OK

WATCH

WATCH key [key ...]

监视一个(或多个) key ,如果在事务执行之前这个(或这些) key 被其他命令所改动,那么事务将被打断。

可用版本:
>= 2.2.0
时间复杂度:
O(1)。
返回值:
总是返回 OK 。
  1. redis> WATCH lock lock_times
  2. OK

UNWATCH

UNWATCH

取消 WATCH 命令对所有 key 的监视。

如果在执行 WATCH 命令之后, EXEC 命令或 DISCARD 命令先被执行了的话,那么就不需要再执行 UNWATCH 了。

因为 EXEC 命令会执行事务,因此 WATCH 命令的效果已经产生了;而 DISCARD 命令在取消事务的同时也会取消所有对 key 的监视,因此这两个命令执行之后,就没有必要执行 UNWATCH 了。

可用版本:
>= 2.2.0
时间复杂度:
O(1)
返回值:
总是 OK 。
  1. redis> WATCH lock lock_times
  2. OK
  3.  
  4. redis> UNWATCH
  5. OK

在前面的基础上,我们来看下使用node_redisioredis的例子:

首先来看下使用node_redis的例子:

node_redis篇

client.multi([commands])

MULTI命令让我们执行的其他命令排队直到执行EXEC命令后,排队的命令才会被自动执行。在node_redis中这个接口通过调用client.multi()来产生一个Multi对象。如果其中有一个命令失败,排队的所有命令都会被回滚,没有命令会执行。

  1. var redis = require("./index"),
  2. client = redis.createClient(), set_size = 20;
  3.  
  4. client.sadd("bigset", "a member");
  5. client.sadd("bigset", "another member");
  6.  
  7. while (set_size > 0) {
  8. client.sadd("bigset", "member " + set_size);
  9. set_size -= 1;
  10. }
  11.  
  12. // multi chain with an individual callback
  13. client.multi()
  14. .scard("bigset")
  15. .smembers("bigset")
  16. .keys("*", function (err, replies) {
  17. // NOTE: code in this callback is NOT atomic
  18. // this only happens after the the .exec call finishes.
  19. client.mget(replies, redis.print);
  20. })
  21. .dbsize()
  22. .exec(function (err, replies) {
  23. console.log("MULTI got " + replies.length + " replies");
  24. replies.forEach(function (reply, index) {
  25. console.log("Reply " + index + ": " + reply.toString());
  26. });
  27. });

Multi.exec([callback])

client.multi()返回一个Multi对象结构,Multi具有和client对象同样的执行命令的方法。要执行的命令在Multi对象中排队知道执行Multi.exec()方法。

如果你的执行,命令中包含了语法错误或者是抛出了EXECABORT错误,那么所有的命令将会停止执行。错误中包含了.errors属性,这个属性中包含了具体的错误信息。如果所有的命令都成功入队,当在执行一条命令的时候redis抛出一个错误,这个错误将会被返回给最终的结果数组!,尽管队列中有一条失败了那么并没有命令会停止(试过几次,确实没有命令会停止,错误的命令并不会引起其他命令退出执行)。

上面我们使用了MULTI命令进行链式调用。我们也可以吧命令放入单独的MULTI构成的队列中,同时也可以用client命令。

  1. var redis = require("redis"),
  2. client = redis.createClient(), multi;
  3.  
  4. // start a separate multi command queue
  5. multi = client.multi();
  6. multi.incr("incr thing", redis.print);
  7. multi.incr("incr other thing", redis.print);
  8.  
  9. // runs immediately
  10. client.mset("incr thing", 100, "incr other thing", 1, redis.print);
  11.  
  12. // drains multi queue and runs atomically
  13. multi.exec(function (err, replies) {
  14. console.log(replies); // 101, 2
  15. });

除了单独添加命令到MULTI队列,你也可以传递一个包含命令和参数的数组。

  1. var redis = require("redis"),
  2. client = redis.createClient(), multi;
  3.  
  4. client.multi([
  5. ["mget", "multifoo", "multibar", redis.print],
  6. ["incr", "multifoo"],
  7. ["incr", "multibar"]
  8. ]).exec(function (err, replies) {
  9. console.log(replies);
  10. });

redis transactions(事务)的更多相关文章

  1. 9、redis之事务2-Jedis的八种调用方式(事务、管道、分布式)介绍

    1.普通同步 @Test public void test1Normal() { Jedis jedis = new Jedis("localhost"); long start ...

  2. redis(4)事务

    一.事务 一般来说,事务必须满足4个条件,也就是我们常说的ACID: 1)Atomicity 原子性:一个事务中的所有操作要么全部完成,要么全部不完成,不会结束在中间的某个环节.事务在执行过程中发生错 ...

  3. Redis的事务

    Redis对事务的支持是部分支持,不想oracle,要么都成功要么都失败,Redis可以部分成功部分失败 1 是什么: 可以一次执行多个命令,本质是一组命令的集合.一个事务中的所有命令都会序列化,按顺 ...

  4. Redis笔记(五)Redis的事务

    >>关系型数据库的事务 事务是应用程序中一系列严密的操作,所有操作必须成功完成,否则在每个操作中所作的所有更改都会被撤消. Atomic(原子性): 一个事务(transaction)中的 ...

  5. 谈谈分布式事务之三: System.Transactions事务详解[下篇]

    在前面一篇给出的Transaction的定义中,信息的读者应该看到了一个叫做DepedentClone的方法.该方法对用于创建基于现有Transaction对 象的“依赖事务(DependentTra ...

  6. 谈谈分布式事务之三: System.Transactions事务详解[上篇]

    在.NET 1.x中,我们基本是通过ADO.NET实现对不同数据库访问的事务..NET 2.0为了带来了全新的事务编程模式,由于所有事务组件或者类型均定义在System.Transactions程序集 ...

  7. redis的事务(简单介绍)

    1.简单描述 redis对事务的支持目前还是比较简单.redis只能保证一个client发起的事务中的命令是可以连续的执行,而中间不会插入其他client的命令.由于redis是但现场来处理所有cli ...

  8. Redis的事务功能详解

    Redis的事务功能详解 MULTI.EXEC.DISCARD和WATCH命令是Redis事务功能的基础.Redis事务允许在一次单独的步骤中执行一组命令,并且可以保证如下两个重要事项: >Re ...

  9. Redis的事务和watch

    redis的事务 严格意义来讲,redis的事务和我们理解的传统数据库(如mysql)的事务是不一样的. redis中的事务定义 Redis中的事务(transaction)是一组命令的集合. 事务同 ...

随机推荐

  1. vue build后运行错误

    events.js:141 throw er; // Unhandled 'error' event 这个是端口占用的问题 $ http-server dist events.js:141 throw ...

  2. 转 VB ListView控件各种操作详解

    Private Sub Form_Load() ListView1.ListItems.Clear '清空列表 ListView1.ColumnHeaders.Clear '清空列表头 ListVie ...

  3. RESTful Web服务的操作

    1.首先我们说一下Http协议是无状态的 HTTP协议是无状态的,我们看到查到的用到的返回404,500,200,201,202,301.这些不是HTTP协议的状态码. 是HTTP的状态码,就是HTT ...

  4. Spring Boot 之 RESTfull API简单项目的快速搭建(三)

    1.运行打包后的项目 java -jar spring-boot-demo-2-1-0.0.1-SNAPSHOT.jar

  5. Webwork【08】结合实战简析Controller 配置

    虽然现在 MVC 框架层出不穷,但做为 Struts 前身的 webwork. 其经典程度不亚于贝利之于足球,双 11 之于淘宝特卖. 本篇将结合 webwork controller 配置文件 xw ...

  6. Python定向爬虫实战

    转载请注明原文地址:http://www.cnblogs.com/ygj0930/p/7019963.html 一:requests模块介绍 requests是第三方http库,可以十分方便地实现py ...

  7. 事件响应的优先级、stopProgapation禁止下层组件响应

    cocos2d-js没有完整的鼠标事件处理,这点比js/flash的要差一些,不过凑合着也可以用了. 一般界面编程,可以用显示列表的Node作为监听器的优先级,在上方的会比下方的高优先级. 而coco ...

  8. java的配置方式简介

    1,java的配置方式简介java的配置方式是为了代替使用xml配置方式,主要使用两个注解:@Configuration//通过该注解来表明该类是一个spring的配置,相当于一个xml文件@Comp ...

  9. Linux手工添加swap

    swap是一把双刃剑,在实践中发现,严重的会导致linux负载超高,失去响应kswap内存的信息转存到swap(硬盘)!,在内存较大的情况下不建议建立swap!!! 师夷长技以制夷! 1.root权限 ...

  10. 51单片机——My-Clock项目

    技术:51单片机.光敏传感器.PCF8591.DHT11.DS1302.OLED显示屏   概述 项目My-Clock是一个环境监测时钟,接入光敏传感器和温湿度传感器监测环境信息,加入DS1302模块 ...