redis transactions(事务)
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_redis与ioredis的例子:
首先来看下使用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);
});
redis transactions(事务)的更多相关文章
- 9、redis之事务2-Jedis的八种调用方式(事务、管道、分布式)介绍
1.普通同步 @Test public void test1Normal() { Jedis jedis = new Jedis("localhost"); long start ...
- redis(4)事务
一.事务 一般来说,事务必须满足4个条件,也就是我们常说的ACID: 1)Atomicity 原子性:一个事务中的所有操作要么全部完成,要么全部不完成,不会结束在中间的某个环节.事务在执行过程中发生错 ...
- Redis的事务
Redis对事务的支持是部分支持,不想oracle,要么都成功要么都失败,Redis可以部分成功部分失败 1 是什么: 可以一次执行多个命令,本质是一组命令的集合.一个事务中的所有命令都会序列化,按顺 ...
- Redis笔记(五)Redis的事务
>>关系型数据库的事务 事务是应用程序中一系列严密的操作,所有操作必须成功完成,否则在每个操作中所作的所有更改都会被撤消. Atomic(原子性): 一个事务(transaction)中的 ...
- 谈谈分布式事务之三: System.Transactions事务详解[下篇]
在前面一篇给出的Transaction的定义中,信息的读者应该看到了一个叫做DepedentClone的方法.该方法对用于创建基于现有Transaction对 象的“依赖事务(DependentTra ...
- 谈谈分布式事务之三: System.Transactions事务详解[上篇]
在.NET 1.x中,我们基本是通过ADO.NET实现对不同数据库访问的事务..NET 2.0为了带来了全新的事务编程模式,由于所有事务组件或者类型均定义在System.Transactions程序集 ...
- redis的事务(简单介绍)
1.简单描述 redis对事务的支持目前还是比较简单.redis只能保证一个client发起的事务中的命令是可以连续的执行,而中间不会插入其他client的命令.由于redis是但现场来处理所有cli ...
- Redis的事务功能详解
Redis的事务功能详解 MULTI.EXEC.DISCARD和WATCH命令是Redis事务功能的基础.Redis事务允许在一次单独的步骤中执行一组命令,并且可以保证如下两个重要事项: >Re ...
- Redis的事务和watch
redis的事务 严格意义来讲,redis的事务和我们理解的传统数据库(如mysql)的事务是不一样的. redis中的事务定义 Redis中的事务(transaction)是一组命令的集合. 事务同 ...
随机推荐
- 安装MySQL-python报错:_mysql.c(42) : fatal error C1083: Cannot open include file: 'config-win.h': No such file or directory或者 build\lib.win-amd64-2.7\_mysql.pyd : fatal error LNK1120: 56 unresolved externa
解决办法1: 直接下载MySQL-python-1.2.5.win-amd64/32-py2.7.exe,点击安装 此处要注意自己安装的Python和MySQL版本是64位还是32位,否则在进行安装M ...
- 透彻理解Ioc
引述:IoC(控制反转:Inverse of Control)是Spring容器的内核,AOP.声明式事务等功能在此基础上开花结果.但是IoC这个重要的概念却比较晦涩隐讳,不容易让人望文生义,这不能不 ...
- Atlas系列一:【已解决】error while loading shared libraries: libcrypto.so.6: cannot open shared object file: No such file or directory
1:Atlas的安装 https://github.com/Qihoo360/Atlas/wiki/Atlas的安装 2: [root@localhost bin]# ./mysql-proxyd t ...
- Linux Shell 下载网站指定文件
Shell脚本,用来从网站下载指定文件名的文件.先判断本地这个文件是否存在,如果存在则忽略,不存在则从远程服务器上下载,下载成功后本地的批次号累加1,然后使用新的批次号继续下载新文件. #!/bin/ ...
- OpenCV在Windows平台下的源代码编译
OpenCV库官方站点为http://opencv.org/. 在该站点能够下载最新的OpenCV for Windows,比如当前我下载的是opencv-2.4.9.exe ,双击该文件解压到某个文 ...
- kettle 如何将excel文件导入oracle数据库?
1.情景展示 昨日,有一批数据需要导入数据库,但是,plsql不知为何不能导了,于是,我选择使用kettle完成excel数据的导入. 2.准备工作 将对应的数据库所需的jar包拷贝至其lib目录 ...
- [Android]Recovery调用外部Shell脚本,Shell脚本使用ui_print方法
busybox_bin=/sbin/busybox # 获取PIPE get_outfd(){ | $busybox_bin grep -q 'pipe'; then else local all_p ...
- Lotus Domino开发心得(一)
—- Lotus Domino 是当今办公自动化系统的主流开发平台之一,目前大部分企业和机构都在使用Lotus Domino 开发自己的无纸办公系统.在开发过程中,我积累了一些小技巧,现在公布出来,希 ...
- javascript基础 思维导图2
来源于:http://www.cnblogs.com/xianyulaodi/p/5886128.html 1.javascript数据类型 2.javascript数组 3.javascript运算 ...
- 在centos 5.5 i386 上安装 oracle 10g xe
1.安装rpm包 nano /v.sh 将下面内容复制进去 #!/bin/bash rpm -Uvh compat-db-4.2.52-5.1.i386.rpm rpm -Uvh compat-lib ...