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 - 事务操作的更多相关文章

  1. Redis事务操作

    Redis事务操作 Redis事务本质: ​ 一组命令的集合 , 一个事务中的所有命令都会被序列化 , 在事务执行过程中 , 会按照顺序执行 一次性 : 事务之间的事情,会一次性执行,而不是立刻执行 ...

  2. Spring Framework 中启动 Redis 事务操作

    背景: 项目中遇到有一系列对Redis的操作,并需要保持事务处理. 环境: Spring version 4.1.8.RELEASE Redis Server 2.6.12 (64位) spring- ...

  3. C#Redis 事务操作

    一.理论 还是抄前辈的理论知识. 和众多其它数据库一样,Redis作为NoSQL数据库也同样提供了事务机制.在Redis中,MULTI/EXEC/DISCARD/WATCH这四个命令是我们实现事务的基 ...

  4. [Redis-CentOS7]Redis事务操作(六)

    事务操作 隔离操作: 事务中所有的命令都会序列化,按顺序执行,不会被其他命令打扰 原子操作: 事务中所有的命令要么全部执行,要么全部不执行 添加事务并执行 127.0.0.1:6379> MUL ...

  5. Redis - 事务操作与详解

    https://blog.csdn.net/J080624/article/details/81669560   写的比较清楚的一个帖子

  6. spring的声明式事务,及redis事务。

    Redis的事务功能详解 http://ghoulich.xninja.org/2016/10/12/how-to-use-transaction-in-redis/ MULTI.EXEC.DISCA ...

  7. 一次 Redis 事务使用不当引发的生产事故

    这是悟空的第 170 篇原创文章 官网:http://www.passjava.cn 你好,我是悟空. 本文主要内容如下: 一.前言 最近项目的生产环境遇到一个奇怪的问题: 现象:每天早上客服人员在后 ...

  8. python实现redis三种cas事务操作

    cas全称是compare and set,是一种典型的事务操作. 简单的说,事务就是为了存取数据库中同一数据时不破坏操作的隔离性和原子性,从而保证数据的一致性. 一般数据库,比如MySql是如何保证 ...

  9. Redis源代码分析(十七)--- multi事务操作

    redis作为一非关系型数据库,居然相同拥有与RDBMS的事务操作,不免让我认为比較吃惊.在redis就专门有文件就是运行事务的相关操作的.也能够让我们领略一下.在Redis的代码中是怎样实现事务操作 ...

随机推荐

  1. Oracle 字符集常见字符集及解决方案

    Oracle 字符集常见字符集及解决方案 优先级别:alter session>环境变量>注册表>参数文件 一.查看字符集: 1.查询服务端字符集: select userenv(' ...

  2. WebGL 一

    WebGL绘制窗口 <html><head><title>OpenGL Test</title> </head><body>&l ...

  3. iOS开发其他相关

    1.iOS开发行情 1.1 iOS系统各个版本的占比查询 2.Xcode的使用 开发软件下载 Xcode Help(官方) 2.1 Xcode面板 Xcode面板 2.2 Xcode版本新功能 Xco ...

  4. js计算机样式window.getComputedStyle(ele,null)与

    一.getComputedStyle兼容IE8以上,范户籍的计算样式的值都是绝对值,没有相对单位(如:width:10em; 它打印出来是160px) window.getComputedStyle( ...

  5. “全栈2019”Java第四十章:this关键字

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第 ...

  6. CF1059C Sequence Transformation 题解

    这几天不知道写点什么,状态也不太好,搬个题上来吧 题意:给定一个数n,设一个从1到n的序列,每次删掉一个序列中的数,求按字典序最大化的GCD序列 做法:按2的倍数找,但是如果除2能得到3的这种情况要特 ...

  7. 方法引用(Method reference)和invokedynamic指令详细分析

    方法引用(Method reference)和invokedynamic指令详细分析 invokedynamic是jvm指令集里面最复杂的一条.本文将详细分析invokedynamic指令是如何实现方 ...

  8. [集合]Collection集合框架源码分析

    Collection接口 在java的集合类库中,基本接口是Collection,该接口的在集合中的源码定义如下(将源码中的注释删掉了): public interface Collection< ...

  9. Java学习笔记01

    1.原型设计: 将页面的模块.元素.人机交互的形式,利用线框描述的方法,将产品脱离皮肤状态下更加具体跟生动的进行表达. 2.下面的是使用PowerDesigner进行设计的持久层的层次结构图: 虚线三 ...

  10. 使用IntelliJ IDEA 前最好修改的配置

    目录 1.下载 2.破解 3.修改配置 下载 详见我的另外一篇博客:<软件开发资源下载>中的[IDE]->[IntelliJ IDEA] 破解 详见我的另外一篇博客:<最新版I ...