Redis - 事务操作
Redis的事务基于四个命令:
- MULTI
- EXEC
- DISCARD
- WATCH
创建事务
Redis的事务从一个MULTI命令开始,MULTI总会命令返回"ok"。
接着就可以开始输入操作数据,每一条操作命令都会进入队列。
最后执行EXEC,在队列中的命令得到执行。
比如这样:
> MULTI
OK
> INCR foo
QUEUED
> INCR bar
QUEUED
> EXEC
1) (integer) 1
2) (integer) 1
如果事务中出现错误怎么办?
首先我们将事务中的错误分为两类:
- 进入队列前发现错误,比如命令的语法错误。
- EXEC执行后发现错误,比如对同一个key执行的两次不同数据类型的操作。
第一种很好理解,就像上面给出的例子中,成功进入队列后会立马返回"QUEUED"。
如果没能进入队列,则整个事务都会失效,提示"Transaction discarded because of previous errors."
关于EXEC执行后出现的错误,凡是成功进入队列的都会被执行,即便同一事物中有执行失败的命令,其余的命令都会得到执行。
这让那些用过关系型数据库的人们感到诧异, 为什么Redis不支持roll back?
对此官网的两点说法:
Redis commands can fail only if called with a wrong syntax (and the problem is not detectable during the command queueing), or against keys holding the wrong data type: this means that in practical terms a failing command is the result of a programming errors, and a kind of error that is very likely to be detected during development, and not in production.
Redis is internally simplified and faster because it does not need the ability to roll back.
有人说不支持roll back会引发各种bug。但需要明白的是,roll back不是用来解决编程层面上的错误的。
而且,导致命令失败只有两种可能:
- 语法错误
- 执行了与key的数据类型不匹配的操作
鉴于此,roll back几乎没有任何意义,Redis更倾向于不支持roll back而是保持简洁和高效。
丢弃事务
DISCARD可以用作丢弃当前事务,并将连接状态恢复为正常状态。
使用方法如下:
> SET foo 1
OK
> MULTI
OK
> INCR foo
QUEUED
> DISCARD
OK
> GET foo
"1"
原子性
check-and-set(CAS)之类的操作往往会出现竟态条件。
Redis提供了WATCH用于观察key的变化。
当一个被观察的key在EXEC执行前变化时,整个事务会终止并返回Nil,对该key的观察也会结束。
刚接触WATCH的时候,感觉这种处理方式很晦涩。不能加个显示锁什么的吗?
好在官网给出了充分的说明,先假设Redis没有提供INCR,我们现在要模拟一个递增操作:
val = GET mykey
val = val + 1
SET mykey $val
一个client进行该操作时是没有问题,但多个client一起进行该操作时会出现竟态条件。
比如A和B两个client同时进行了GET mykey,得到的都是10,因此两次执行的结果是11而不是12。
而加入WATCH后:
WATCH mykey
val = GET mykey
val = val + 1
MULTI
SET mykey $val
EXEC
如果WATCH和EXEC之间有其他的什么东东改变了被观察的key,该事务则会失败。
如果希望本次事务执行成功则需要在循环中执行,当然,这也是一种locking方式。
事实上,多个client访问同一key的冲突并不常见,看具体情况进行操作吧。
相应地,也有UNWATCH可以用于释放所有被观察的key。
比如下面的例子中,事务内的INCR会成功执行:
WATCH key
UNWATCH key
MULTI
INCR key
EXEC
关于WATCH,需要注意的一点是:设置了生存时间(EXPIRE)的key不会因为到期而被WATCH当作以改变。
Redis - 事务操作的更多相关文章
- Redis事务操作
Redis事务操作 Redis事务本质: 一组命令的集合 , 一个事务中的所有命令都会被序列化 , 在事务执行过程中 , 会按照顺序执行 一次性 : 事务之间的事情,会一次性执行,而不是立刻执行 ...
- Spring Framework 中启动 Redis 事务操作
背景: 项目中遇到有一系列对Redis的操作,并需要保持事务处理. 环境: Spring version 4.1.8.RELEASE Redis Server 2.6.12 (64位) spring- ...
- C#Redis 事务操作
一.理论 还是抄前辈的理论知识. 和众多其它数据库一样,Redis作为NoSQL数据库也同样提供了事务机制.在Redis中,MULTI/EXEC/DISCARD/WATCH这四个命令是我们实现事务的基 ...
- [Redis-CentOS7]Redis事务操作(六)
事务操作 隔离操作: 事务中所有的命令都会序列化,按顺序执行,不会被其他命令打扰 原子操作: 事务中所有的命令要么全部执行,要么全部不执行 添加事务并执行 127.0.0.1:6379> MUL ...
- Redis - 事务操作与详解
https://blog.csdn.net/J080624/article/details/81669560 写的比较清楚的一个帖子
- spring的声明式事务,及redis事务。
Redis的事务功能详解 http://ghoulich.xninja.org/2016/10/12/how-to-use-transaction-in-redis/ MULTI.EXEC.DISCA ...
- 一次 Redis 事务使用不当引发的生产事故
这是悟空的第 170 篇原创文章 官网:http://www.passjava.cn 你好,我是悟空. 本文主要内容如下: 一.前言 最近项目的生产环境遇到一个奇怪的问题: 现象:每天早上客服人员在后 ...
- python实现redis三种cas事务操作
cas全称是compare and set,是一种典型的事务操作. 简单的说,事务就是为了存取数据库中同一数据时不破坏操作的隔离性和原子性,从而保证数据的一致性. 一般数据库,比如MySql是如何保证 ...
- Redis源代码分析(十七)--- multi事务操作
redis作为一非关系型数据库,居然相同拥有与RDBMS的事务操作,不免让我认为比較吃惊.在redis就专门有文件就是运行事务的相关操作的.也能够让我们领略一下.在Redis的代码中是怎样实现事务操作 ...
随机推荐
- Mysql数据操作《一》数据的增删改
插入数据INSERT 1. 插入完整数据(顺序插入) 语法一: INSERT INTO 表名(字段1,字段2,字段3…字段n) VALUES(值1,值2,值3…值n); 语法二: INSERT INT ...
- 【English】20190430
Network security网络安全[ˈnetwɜːrk] [sɪˈkjʊrəti] Teradata Generic Security Service 通用安全服务[dʒəˈnerɪk] [s ...
- 一个标准的AJAX请求
这是一个标准的ajax请求: $.ajax({ type:"post", url:basePath+"/resourcePush/operationLog", ...
- [转] 配置文件现在需要绝密的短语密码(blowfish_secret)的解决方法
今天在使用 phpMyAdmin 操作数据库时,刚刚登陆后发现最下面有如下信息提示: 配置文件现在需要绝密的短语密码(blowfish_secret). 园子在网上找了多种解决方法,写的都不是非常详细 ...
- PL/SQL数据库开发那点事
PL/SQL数据库开发那点事-->编程,存储程序 在SQL*plus 中编写PL/SQL程序,并在SQL*plus 中执行它, PL/SQL块的代码就存放在SQL*plus的缓冲区中.如果在SQ ...
- Python处理json数据--世界国家维度数据
1.准备国家的json数据 将准备好的json数据放在指定的目录下,此处可以重这里下载 2.测试编写python脚本处理json提取字段值 #coding:utf8 import time, re, ...
- scrollto 到指定位置
goTo = function(target){ var scrollT = document.body.scrollTop|| document.documentElement.scrollTop ...
- 2016级算法第四次上机-B ModricWang的序列问题
1019 ModricWang的序列问题 思路 此题题意非常清晰,给定一个序列,求出最长上升子序列的长度.从数据规模来看,需要\(O(nlogn)\) 的算法. \(O(nlongn)\) 求最长上升 ...
- BZOJ1688 Disease Manangement 疾病管理
Disease Manangement 疾病管理 Description Alas! A set of D (1 <= D <= 15) diseases (numbered 1..D ...
- 进阶篇:4.2.6)DFMEA故障库的建立与积累
本章目的:DFMEA故障库的建立与积累. 1.故障库的认知 故障库是一种数据库,只是这个数据库中储存的是故障模式,也就是失效模式. 从前文DFMEA章节的学习中,我们可以知道,DFMEA对不同层级的失 ...