【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 ...
随机推荐
- Atom与markdown
简述 Atom是github开发的开源跨平台的编辑器,Atom的强大可以与大名鼎鼎的Sublime Text相媲美.因为使用过Sublime Text,所以用Atom上手很快.这篇文章主要介绍使用At ...
- Linux之vmware安装
环境准备 mac 用 vmware fusion 虚拟机 和 iterm2 远程连接工具, ...
- 【2017.12.12】deepin安装U盘制作,支持 BIOS+UEFI,deepin_Recovery+Win PE
U盘要求为 FAT32,MBR分区表 如果需要放 4GB 大文件,可以分两个分区,第一分区FAT32格式,放启动相关文件,第二个分区用 NTFS 格式,放其它资料. 最新 Win10 支持显示 U盘 ...
- db2 Reorgchk:重组检查,是否需要重组
Reorgchk:重组检查,是否需要重组.判断表或索引是否需要重组,有2种方法:1.通过reorgchk工具 reorgchk工具利用8个公式(3个表公式,5个索引公式),如果表统计结果F1,F2或 ...
- Processing-基础小坑-
x 坑A:) 新建一个"Walker"项目,Walker.pde,必须在Walker文件夹下... 刚开始以为如果一个文件需要引用另外一个文件中的类,只要把这两个文件放一个文件夹下 ...
- 网卡配置文件详解 用户管理与文件权限篇 文件与目录权限 软连接 tar解压命令 killall命令 linux防火墙 dns解析设置 计划任务crond服务 软件包安装 阿里云 yum源 安装
Linux系统基础优化及常用命令 Linux基础系统优化 引言没有,只有一张图. Linux的网络功能相当强悍,一时之间我们无法了解所有的网络命令,在配置服务器基础环境时,先了解下网络参数设定命令. ...
- tensorflow使用pb文件进行模型预测
- IP地址、MAC地址及端口
概述: IP 是地址,有定位功能(网与网的通讯) (在逻辑上唯一标识一台电脑)(网络层) MAC 是身份证,无定位功能(在子网干活)(在物理上唯一标识一台电脑) (链路层) 首先是如何查看ip ...
- iOS循环引用常见场景和解决办法
好多场景会导致循环引用,例如使用Block.线程.委托.通知.观察者都可能会导致循环引用. 1.委托 遵守一个规则,委托方持有代理方的强引用,代理方持有委托方的弱引用. 实际场景中,委托方会是一个控制 ...
- flume 学习总结
flume 总结 flume 总结 下载配置安装 1 下载 2 配置安装 flume 架构 agent 配置 1 source 配置 11 监听网络端口 12 监控文件 2 channel 配置 3 ...