文档章节

Redis 事务

learn_more
 learn_more
发布于 2016/09/10 09:48
字数 956
阅读 57
收藏 1

 

先手动执行如下命令,然后看看效果

>multi

>set str1 "hello world"

>"QUEUED"

>set str2 hello world

>"QUEUED"

>set str2 "welcome"

>"QUEUED"

>exec

> 1) "OK"

> 2) "ERR syntax error"

> 3) "OK"

>get str1

>"hello world"

>get str2

>null

>get str3

>welcome

 

1)事务以 multi 开始 exec 结束,在exec执行之前的命令,都会存储在Redis服务端的命令队列里面直到exec调用才会执行,因此,任何multi与exec之间的命令都不会及时反馈结果。因此我们无法在事务里面通过读取Redis数据来做决定,这就说明你只能是在multi之前把需要从Redis获取的数据读取出来,然后在到事务里面去做决定,哈哈,这是不是太蠢了,因为这是脏读。

2)从示例结果你可以看出,事务在set str2 发生语法错误,可是整个结果却没有保证数据的原子性(要么成功,要么失败),因为 str1插入成功,str3插入成功,str2插入失败。这说明Redis服务端执行队列里的命令时遇到错误不会回滚也不会停止运行,Redis是这样设计的,理由是回滚是多余的操作,因为错误都是程序员代码造成的,换句话时候代码中不应该出现错误,也就没必要回滚了。总之, 即使事务中有某条/某些命令执行失败了, 事务队列中的其他命令仍然会继续执行 —— Redis 不会停止执行事务中的命令。

3)那么如何解决数据脏读呢?MySQL使用的事务锁机制,很明显高并发下这是不可取的手段,看看Redis是如何处理的,使用 watch(key1,key2...) 命令,在multi之前执行 watch命令,观察监视一个或多个key,如果在接收到exe命令时发现被监视的任何一个key的值有了变化,那么事务就被取消,这里是有原子性的哦,另外,watch 提供的类似CAS(Compare And Set or Check And Set)功能,另watch 其实是乐观锁机制。

4)watch之后,multi之前,这段代码当中可能就会出现值发生变化的时候,那么我们可以在这之间再来做一个判断,判断值是否满足我们预期,如果不满足预期那么就直接 unwatch(exec、discard之后默认执行了unwatch). 然后不执行事务。这其实就是双重锁定,第一层锁放在watch之前,第二层锁放在watch之后multi之前,是不是很熟悉的操作,没错,经典的懒汉式单例模式。

5)没错,unwatch 是希望在执行事务之前就发现数据已经不满足预期,然后手动控制不要去执行事务,那么discard可以在multi至exec之间执行,把事物取消,同样他取消的是整个事务。

6)使用事务的过程中,事务包裹的命令是不会被其他客户端所打扰,另外,底层客户端也会使用流水线来进一步提高事务执行时的性能,换句话说使用事物就默认使用了流水线操作,但是事务的缺点是资源耗费,还可能导致其他重要命令被延迟执行。

7)来看看完整的事务

>set str1 10

>set str2 100

>watch str1

>//伪代码,如果str2的值没有达到101则取消观察,停止程序. if( str2 <= 100 ) unwatch; return;

>multi

>incr str1

>"QUEUED"

>// 伪代码,这里可以在满足某个条件的情况下取消事务的所有命令,discard

>incr str2

>"QUEUED"

>exec

> 1) 11

> 2) 102

 

 

 

 

© 著作权归作者所有

learn_more
粉丝 93
博文 240
码字总数 210196
作品 0
深圳
程序员
私信 提问
加载中

评论(0)

redis事物详解

Redis中的事务就是一组命令的集合,被依次顺序的执行,当然你可以放弃事务的执 行,那么所有事务里面的命令都不会执行。 关于Redis的事务有几点说明: 1:Redis的事务仅仅是保证事务里的操作...

daydayup08
2016/04/23
48
0
Redis中的事务

事务同命令一样,都是Redis的最小执行单位,一个事务中的命令要么都执行,要么都不执行。 一、Redis事务的实现 Redis通过multi、exec、watch等命令来实现事务功能,Redis中一个事务从开始到结...

u012050154
2017/11/29
0
0
【Redis源码剖析】 - Redis之事务的实现原理

原创作品,转载请标明:http://blog.csdn.net/Xiejingfa/article/details/51262268 Redis源码剖析系列文章汇总:传送门 今天为大家带来Redis中事务部分的源码分析。Redis的事务机制允许将多个...

xiejingfa
2016/04/27
0
0
redis源码分析之事务Transaction(下)

接着上一篇,这篇文章分析一下redis事务操作中multi,exec,discard三个核心命令。 看本篇文章前需要先对上面文章有所了解: redis源码分析之事务Transaction(上) 一、redis事务核心命令简...

凌风郎少
2017/11/12
0
0
Redis中事务ACID支持程度

事务是一个数据库必备的元素,对于redis也不例外,对于一个传统的关系型数据库来说,数据库事务满足ACID四个特性: A代表原子性:一个事务(transaction)中的所有操作,要么全部完成,要么全...

石日天
2019/03/27
94
1

没有更多内容

加载失败,请刷新页面

加载更多

django

aiodns 1.1.1aiohttp 3.6.1asn1crypto 0.24.0async-timeout 3.0.1attrs 19......

MtrS
3分钟前
0
0
SQL查询单表数据(一)

本节讲述 基本的 select 查询单表数据语句 1 从单表中查询所有的行和列 查询表中所有的数据 select * from t_user 在 SQL 中,字符 "*" 具有特殊的含义,使用用它,将从指定的表中返回每一列...

赵子龙
10分钟前
5
0
签名与无符号整数

我是否正确地说有符号和无符号整数之间的区别是: 无符号可以保持较大的正值,而不是负值。 无符号使用前导位作为值的一部分,而带符号版本使用最左侧位来标识数字是正数还是负数。 有符号整...

javail
15分钟前
25
0
【Vue_05】前端工程化

一、ES6的模块化 1. ES6模块化规范 每个 js 文件都是一个独立的模块 导入模块成员使用 import 关键字 暴露模块成员使用 export 关键字 2. 基本语法 发使用 export default { }导出默认成员 ...

Demo_Null
16分钟前
18
0
阿里P7高级架构师分享6年多的Java工作经验(想冲破瓶颈者必看)

很多工作了五年左右的程序员每天已经习惯了机器般的写代码,如果是这样那么你永远只会是个基础程序员,因为你不能只会用,你要知道原理,不至于让你自己实现一个出来,但是基本原理要知道。 ...

JAVA一方
28分钟前
15
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部