【Redis】事务
在Redis中,事务是以multi/exec/discard进行的, 其中multi表示事务的开始, exec表示事务的执行,discard表示丢弃事务。
127.0.0.1:> multi # 事务的开始
OK
127.0.0.1:> set 1 # 添加命令
QUEUED
127.0.0.1:> set 2
QUEUED
127.0.0.1:> exec # 执行事务
) OK
) OK
127.0.0.1:> get
""
127.0.0.1:> get
""
127.0.0.1:>
127.0.0.1:> multi # 事务的开始
OK
127.0.0.1:> set 3 # 添加命令
QUEUED
127.0.0.1:> set
QUEUED
127.0.0.1:> discard #丢弃事务
OK
127.0.0.1:> exec # 此时在执行exec命令会报错。
(error) ERR EXEC without MULTI
127.0.0.1:>
上面演示了一个完整的事务过程,所有的指令在 exec 之前不执行,而是缓存在服务器的一个事务队列中,服务器一旦收到 exec 指令,才开执行整个事务队列,执行完毕后一次性返回所有指令的运行结果。因为 Redis 的单线程特性,它不用担心自己在执行队列的时候被其它指令打断,可以保证他们能得到的“原子性”执行。另外QUEUED没什么特别的意味,就像OK一样,他只是申明命令已经放入缓存队列中了。
redis原子性?
在mysql中事务会有一个原子执行,如果在事务中一个命令执行时发生错误,其他命令也不会得到执行,但是在redis中是否存在这样的设置?
127.0.0.1:> multi # 事务的开始
OK
127.0.0.1:> set 's'
QUEUED
127.0.0.1:> INCR
QUEUED
127.0.0.1:> set 'ss'
QUEUED
127.0.0.1:> exec
) OK
) (error) ERR value is not an integer or out of range # 因为键为1的值为字符串,不能对其自增,因此报错。
) OK
127.0.0.1:> mget 2 # 键值对2 ‘ss'还是设置成功。
) "s"
) "ss"
从上面我们可以看出,即使在Redis事务中存在错误的命令,也不会妨碍后面的命令执行。
redis中管道
在上面 Redis 事务例子中,在发送每个指令到事务缓存队列时都要经过一次网络读写,当一个事务内部的指令较多时,需要的网络 IO 时间也会线性增长。所以通常 Redis 的客户端在执行事务时都会结合 pipeline 一起使用,这样可以将多次 IO 操作压缩为单次 IO 操作。来增加性能。
import redis re = redis.Redis('localhost', , db =) p = re.pipeline(transaction=True)
p.multi()
p.set('test_1', 'test——1')
p.set('test_2', 'test_2')
p.execute() # redis 客户端中查询结构
127.0.0.1:> get test_1
"test\xe2\x80\x94\xe2\x80\x941"
127.0.0.1:> get test_2
"test_2"
127.0.0.1:>
watch命令
假如有多个客户端会并发进行操作。我们可以通过 Redis 的分布式锁来避免冲突,这是一个很好的解决方案。但是分布式锁是一种悲观锁,那是不是可以使用乐观锁的方式来解决冲突呢?
有这样一种情况,假如多个用户进行并发操作时,需要将值取出然后操作再回写到对应键的值上,这可能会导致最终的值不是正确的值。这里一种解决办法是分布式锁(悲观所),另一种就是Watch(乐观锁)。
watch命令会在事务开始之前看住 1 个或多个指定变量,当服务器收到了 exec 指令要顺序执行缓存的事务队列时,Redis 会检查关键变量自 watch 之后,是否被修改了 (包括当前事务所在的客户端)。如果关键变量被人动过了,exec 指令就会返回 null 回复告知客户端事务执行失败,这个时候客户端一般会选择重试。(watch必须再事务之前执行,不能再事务中执行)
127.0.0.1:> set 'test'
OK
127.0.0.1:> watch test
OK
127.0.0.1:> INCR test # watch之后改变test的值
(integer)
127.0.0.1:> multi # 开始事务
OK
127.0.0.1:> INCR test # 改变test的值
QUEUED
127.0.0.1:> exec # 执行事务
(nil) # 返回空值,事务执行失败。 127.0.0.1:> set 'test_2' # 设置test-
OK
127.0.0.1:> watch test_2 # 监听test_2
OK
127.0.0.1:> multi
OK
127.0.0.1:> INCR test_2 #修改test_2的值
QUEUED
127.0.0.1:> exec # 执行成功
) (integer)
在py客户端中对于一个值的修改我们可以采用这样形式
import redis def modify_test(client, key):
while True:
client.watch(key)
value = int(client.get(key))
value += # 修改值
pipe = client.pipeline(transaction=True)
pipe.multi()
pipe.set(key, value)
try:
pipe.execute()
break # 修改成功
except redis.WatchError:
continue # 值已经被修改,执行失败
return int(client.get(key)) # 重新获取值 client = redis.StrictRedis()
key = "test"
client.setnx(key, ) # setnx 做初始化
print (modify_test(client, key))
【Redis】事务的更多相关文章
- Redis学习笔记~Redis事务机制与Lind.DDD.Repositories.Redis事务机制的实现
回到目录 Redis本身支持事务,这就是SQL数据库有Transaction一样,而Redis的驱动也支持事务,这在ServiceStack.Redis就有所体现,它也是目前最受业界认可的Redis ...
- Redis学习笔记(4) Redis事务、生存时间及排序
1. Redis事务 Redis中的事务(transaction)是一组命令的集合,一个事务中的命令要么都执行,要么都不执行.事务的原理是先将属于一个事务的命令发送给Redis,然后再让Redis依次 ...
- REDIS 事务机制
基本事务操作: 任何数据库都必须要保证一种原子执行操作:最基本的原子执行操作肯定是需要提供: 举一个例子来说明: 当对某个Key 做一个统计: 可能不同的Client做它那部分的统计,一段时间后,服务 ...
- redis 事务
概述 相信学过MySQL等其他数据库的同学对事务这个词都不陌生,事务表示的是一组动作,这组动作要么全部执行,要么全部不执行.为什么会有这样的需求呢?看看下面的场景: 微博是一个弱关系型社交网络,用户之 ...
- (6)redis 事务
redis对事务的支持目前还比较简单.redis只能保证一个client发起的事务中的命令可以连续的执行,而中间不会插入其他client的命令. 由于redis是单线程来处理所有client的请求的所 ...
- Redis事务的分析及改进
Redis事务的分析及改进 Redis的事务特性 数据ACID特性满足了几条? 为了保持简单,redis事务保证了其中的一致性和隔离性: 不满足原子性和持久性: 原子性 redis事务在执行的中途遇到 ...
- Spring Framework 中启动 Redis 事务操作
背景: 项目中遇到有一系列对Redis的操作,并需要保持事务处理. 环境: Spring version 4.1.8.RELEASE Redis Server 2.6.12 (64位) spring- ...
- 2016022612 - redis事务命令集合
参考地址:http://www.yiibai.com/redis/redis_transactions.html Redis事务由指令 MULTI 启动,以EXEC结束. 1.multi 用途:事务开 ...
- 2016022606 - redis事务
Redis事务 Redis事务让一组命令在单个步骤执行.事务中有两个属性,说明如下: 1.在一个事务中的所有命令按顺序执行作为单个隔离操作.通过另一个客户端发出的请求在Redis的事务的过程中执行,这 ...
- Redis事务和分布式锁
Redis事务 Redis中的事务(transaction)是一组命令的集合.事务同命令一样都是Redis最小的执行单位,一个事务中的命令要么都执行,要么都不执行.Redis事务的实现需要用到 MUL ...
随机推荐
- 一、在windows环境下修改pip镜像源的方法(以python3为例)
在windows环境下修改pip镜像源的方法(以python3为例) 1.在windows文件管理器中,输入 %APPDATA% 2.会定位到一个新的目录下,在该目录下新建pip文件夹,然后到pip文 ...
- 【TOP100案例专访】当当网工程师林嘉琦谈双11大促经验及APM实践
导读:第七届TOP100全球软件案例研究峰会将于11月30日-12月3日在北京国家会议中心举办,本届峰会以“释放AI生产力 让组织向智能化演进”为开幕式主题,旨在推动企业在趋势下拥抱AI.探索和思考A ...
- python中的os
import sys, os print(__file__) # 绝对路径,实际是文件名 /Users/majianyu/Desktop/test/bin/bin.py print(os.path.a ...
- HDU 2072 - 单词数 - [(有点小坑的)字典树模板题]
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2072 Problem Descriptionlily的好朋友xiaoou333最近很空,他想了一件没有 ...
- [No000011A]Office Excel设置显示日期与星期
设置excel日期格式,自定义,yyyy-mm-dd 上午/下午 hh:mm:ss AM/PM dddd aaaa
- java 验证字符串是否包含中文字符
中文的模式:"[\\u4e00-\\u9fa5]|\\\\u" 例子: private static final Pattern p = Pattern.compile(" ...
- phpstorm之ssh链接远程Linux服务器
save ssh session inPHPstorm. open PHPstorm,open File,> Settings >search for 'Deployment' > ...
- [administrative] windows 下制作USB启动盘的工具
arch魔教的文档: https://wiki.archlinux.org/index.php/USB_flash_installation_media windows 下的 dd: https:/ ...
- 图->定义
文字描述 顶点 指图中的数据元素 弧尾 若<v,w>属于两个顶点之间的关系的集合,表示从v到w的一条弧,则v为弧尾或初始点 弧头 若<v,w>属于两个顶点之间的关系的集合,表 ...
- 《HTTP - 基于http的认证》
推荐一首歌 - 好吧,今天刚入职第二天,也没听歌. 哈哈哈哈. 1:何为认证? - 其实这个问题就比较宽泛了,总的来说,就是你有证明你身份的标识. - 和人类社会一样,你花了钱想看一场场演唱会,但是谁 ...