MULTI

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

可用版本:>= 1.2.0

时间复杂度:O(1)。

返回值:总是返回 OK。

    redis> MULTI            # 标记事务开始
OK redis> INCR user_id # 多条命令按顺序入队
QUEUED redis> INCR user_id
QUEUED redis> INCR user_id
QUEUED redis> PING
QUEUED redis> EXEC # 执行
) (integer)
) (integer)
) (integer)
) PONG

EXEC

EXEC

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

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

可用版本:
>= 1.2.0
时间复杂度:
事务块内所有命令的时间复杂度的总和。
返回值:
事务块内所有命令的返回值,按命令执行的先后顺序排列。
当操作被打断时,返回空值 nil 。
# 事务被成功执行

redis> MULTI
OK redis> INCR user_id
QUEUED redis> INCR user_id
QUEUED redis> INCR user_id
QUEUED redis> PING
QUEUED redis> EXEC
) (integer)
) (integer)
) (integer)
) PONG # 监视 key ,且事务成功执行 redis> WATCH lock lock_times
OK redis> MULTI
OK redis> SET lock "huangz"
QUEUED redis> INCR lock_times
QUEUED redis> EXEC
) OK
) (integer) # 监视 key ,且事务被打断 redis> WATCH lock lock_times
OK redis> MULTI
OK redis> SET lock "joe" # 就在这时,另一个客户端修改了 lock_times 的值
QUEUED redis> INCR lock_times
QUEUED redis> EXEC # 因为 lock_times 被修改, joe 的事务执行失败
(nil)

DISCARD

DISCARD

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

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

可用版本:
>= 2.0.0
时间复杂度:
O(1)。
返回值:
总是返回 OK 。
redis> MULTI
OK redis> PING
QUEUED redis> SET greeting "hello"
QUEUED redis> DISCARD
OK

WATCH

WATCH key [key ...]

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

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

UNWATCH

UNWATCH

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

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

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

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

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

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

node_redis篇

client.multi([commands])

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

var redis  = require("./index"),
client = redis.createClient(), set_size = 20; client.sadd("bigset", "a member");
client.sadd("bigset", "another member"); while (set_size > 0) {
client.sadd("bigset", "member " + set_size);
set_size -= 1;
} // multi chain with an individual callback
client.multi()
.scard("bigset")
.smembers("bigset")
.keys("*", function (err, replies) {
// NOTE: code in this callback is NOT atomic
// this only happens after the the .exec call finishes.
client.mget(replies, redis.print);
})
.dbsize()
.exec(function (err, replies) {
console.log("MULTI got " + replies.length + " replies");
replies.forEach(function (reply, index) {
console.log("Reply " + index + ": " + reply.toString());
});
});

Multi.exec([callback])

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

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

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

var redis  = require("redis"),
client = redis.createClient(), multi; // start a separate multi command queue
multi = client.multi();
multi.incr("incr thing", redis.print);
multi.incr("incr other thing", redis.print); // runs immediately
client.mset("incr thing", 100, "incr other thing", 1, redis.print); // drains multi queue and runs atomically
multi.exec(function (err, replies) {
console.log(replies); // 101, 2
});

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

var redis  = require("redis"),
client = redis.createClient(), multi; client.multi([
["mget", "multifoo", "multibar", redis.print],
["incr", "multifoo"],
["incr", "multibar"]
]).exec(function (err, replies) {
console.log(replies);
});

最新文章

  1. 配置SSH框架的心得
  2. Oracle表空间数据文件移动的方法
  3. objective-c系列-NSDictionary&NSMutableDictionary
  4. svn删除所有.svn文件
  5. Python 基础【第四篇】参数
  6. makefile--编译出现,未定义的字符
  7. 启用DHCP中继代理,实现跨子网服务 - Win 2003 Server
  8. iscroll5 版本下的 上拉,下拉 加载数据
  9. windows+Ubuntu双系统 windows引导修复
  10. cocoaPods打包的静态库
  11. 说说Java代理模式
  12. node07
  13. mysql插入操作跳过(ignore)、覆盖(replace into)、更新(on duplicate key)
  14. 线性代数笔记13——Ax=b的通解
  15. vue-router2.0
  16. C#通过代码调用PowerShell
  17. SqlServer 连接远程服务器数据库 实现跨服务器联合查询
  18. PHP 如何 安全配置
  19. linux下so获得自己文件位置的路径
  20. Python实例---基于页面的后台管理[简单版]

热门文章

  1. SSH小问题:WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!
  2. Webwork【03】核心类 ServletDispatcher 的初始化
  3. JQuery EasyUI学习笔记
  4. 使用tar+pigz+ssh实现大数据的高效传输
  5. 〖Windows〗三星(SAMSUNG)905S3G-K07 安装Windows 7 过程分享
  6. 【Linux】常见Linux默认的shell
  7. N皇后问题【递归求解】
  8. ios中uiview 转场动画
  9. hihocoder第233周
  10. iOS 开发中的 Tips(一)