Redis 源码学习之 Redis 事务Nosql
Redis事务提供了一种将多个命令请求打包,然后一次性、按照顺序地执行多个命令的机制,并且在事务执行的期间,服务器不会中断事务而去执行其他不在事务中的命令请求,它会把事务中所有的命令都执行完毕才会去执行其他的命令。
How
Redis中提供了multi、discard、exec、watch、unwatch这几个命令来实现事务的功能。
Redis的事务始于multi命令,之后跟着要在事务中执行的命令,终于exec命令或者discard命令。加入事务中的所有命令会原子的执行,中间不会穿插执行其他没有加入事务的命令。
multi、exec和discard
multi命令告诉Redis客户端要开始一个事物,然后Redis会返回一个OK,接下来所有的命令Redis都不会立即执行,只会返回QUEUED结果,直到遇到了exec命令才会去执行之前的所有的命令,或者遇到了discard命令,会抛弃执行之前加入事务的命令。
127.0.0.1:6379> get name
(nil)
127.0.0.1:6379> get gender
(nil)
127.0.0.1:6379> multi
OK
127.0.0.1:6379> set name Slogen
QUEUED
127.0.0.1:6379> set gender male
QUEUED
127.0.0.1:6379> exec
1) OK
2) OK
127.0.0.1:6379> mget name gender
1) "Slogen"
2) "male"
watch
watch命令是Redis提供的一个乐观锁,可以在exec执行之前,监视任意数量的数据库key,并在exec命令执行的时候,检测被监视的key是否至少有一个已经被修改,如果是的话,服务器将拒绝执行事务,并向客户端返回代表事务执行失败的空回复。
首先在client1执行下列命令:
127.0.0.1:6379> get name
(nil)
127.0.0.1:6379> watch name
OK
127.0.0.1:6379> multi
OK
127.0.0.1:6379> set name slogen
QUEUED
127.0.0.1:6379> set gender male
QUEUED
127.0.0.1:6379> get name
QUEUED
这个时候client还没有执行exec命令,接下来在client2下执行下面命令修改name:
127.0.0.1:6379> set name rio
OK
127.0.0.1:6379> get name
"rio"
接下来在client1下执行exec命令:
127.0.0.1:6379> exec
(nil)
127.0.0.1:6379> get name
"rio"
从执行结果可以看到,在client1中执行exec命令的时候,Redis会检测到name字段已经被其他客户端修改了,所以拒绝执行事务中所有的命令,直接返回nil表示执行失败。这个时候获取到的name的值还是在client2中设置的rio。
Why
multi
Redis的事务始于multi命令,那么就从multi命令的源代码开始分析。
当Redis接收到客户端发送过来的命令之后会执行multiCommand()这个方法,这个方法在multi.c文件中。
void multiCommand(client *c) {
// 1. 如果检测到flags里面已经包含了CLIENT_MULTI
// 表示对应client已经处于事务的上下文中,返回错误
if (c->flags & CLIENT_MULTI) {
addReplyError(c,"MULTI calls can not be nested");
return;
}
// 2. 开启flags的CLIENT_MULTI标识
c->flags |= CLIENT_MULTI;
// 3. 返回ok,告诉客户端已经成功开启事务
addReply(c,shared.ok);
}
从源代码中可以看到,multiCommand()主要完成下面三件事:
检测发送multi命令的client是否已经处于事务中,如果是则直接返回错误。从这里可以看到,Redis不支持事务嵌套执行。
给对应client的flags标志位中增加MULTI_CLIENT标志,表示已经进入事务中。
返回OK告诉客户端已经成功开启事务。
Redis 源码学习之 Redis 事务Nosql的更多相关文章
- Redis源码学习:字符串
Redis源码学习:字符串 1.初识SDS 1.1 SDS定义 Redis定义了一个叫做sdshdr(SDS or simple dynamic string)的数据结构.SDS不仅用于 保存字符串, ...
- Redis源码学习:Lua脚本
Redis源码学习:Lua脚本 1.Sublime Text配置 我是在Win7下,用Sublime Text + Cygwin开发的,配置方法请参考<Sublime Text 3下C/C++开 ...
- redis源码学习之slowlog
目录 背景 环境说明 redis执行命令流程 记录slowlog源码分析 制造一条slowlog slowlog分析 1.slowlog如何开启 2.slowlog数量限制 3.slowlog中的耗时 ...
- 柔性数组(Redis源码学习)
柔性数组(Redis源码学习) 1. 问题背景 在阅读Redis源码中的字符串有如下结构,在sizeof(struct sdshdr)得到结果为8,在后续内存申请和计算中也用到.其实在工作中有遇到过这 ...
- __sync_fetch_and_add函数(Redis源码学习)
__sync_fetch_and_add函数(Redis源码学习) 在学习redis-3.0源码中的sds文件时,看到里面有如下的C代码,之前从未接触过,所以为了全面学习redis源码,追根溯源,学习 ...
- Spring5.0源码学习系列之事务管理概述
Spring5.0源码学习系列之事务管理概述(十一),在学习事务管理的源码之前,需要对事务的基本理论比较熟悉,所以本章节会对事务管理的基本理论进行描述 1.什么是事务? 事务就是一组原子性的SQL操作 ...
- redis源码学习之工作流程初探
目录 背景 环境准备 下载redis源码 下载Visual Studio Visual Studio打开redis源码 启动过程分析 调用关系图 事件循环分析 工作模型 代码分析 动画演示 网络模块 ...
- redis源码学习之lua执行原理
聊聊redis执行lua原理 从一次面试场景说起 "看你简历上写的精通redis" "额,还可以啦" "那你说说redis执行lua脚本的原理&q ...
- 玩一把redis源码(一):为redis添加自己的列表类型
2019年第一篇文档,为2019年做个良好的开端,本文档通过step by step的方式向读者展示如何为redis添加一个数据类型,阅读本文档后读者对redis源码的执行逻辑会有比较清晰的认识,并且 ...
随机推荐
- 记录:vue结合springboot进行分页查询和按条件进行查询
界面: 主要代码: 搜索框: <el-form ref="searchForm" :inline="true" :model="searchMa ...
- 如何做系列(4)-微博URL短网址生成算法原理(java版、php版实现实例)
短网址(Short URL),顾名思义就是在形式上比较短的网址.通常用的是asp或者php转向,在Web 2.0的今天,不得不说,这是一个潮流.目前已经有许多类似服务,借助短网址您可以用简短的网址替代 ...
- UOJ#449 喂鸽子
题意:有n个鸽子,你每秒随机喂一只鸽子,每只鸽子吃k次就饱了.求期望多少秒之后全饱了.n <= 50, k <= 1000. 解:有两种做法.一种直接DP的n2k做法在这.我用的是Min- ...
- SQLServer-SQLServer2017:SQLServer2017
ylbtech-SQLServer-SQLServer2017:SQLServer2017 微软推出了首个公共预览版本,并持续带来更新和改进.而今天,微软同时向 Windows.Linux.macOS ...
- mysql利用MySQLWorkbench生成数据表之间的关系图
先看结果,默认是展开的,我手动把表折叠了 那么如何实现呢 先点击这里 然后通过向导来创建即可,一直到finish就行了
- 谷歌浏览器flash被禁用解决方法
谷歌浏览器访问设置:chrome://settings/content/flash 把要启动flash插件的网址添加进去
- Mac下,spacy配置
pip3 install -U spacy -i http://pypi.douban.com/simple --trusted-host pypi.douban.com python3 -m spa ...
- TCP/TP:DNS区域(Zone)
之前阅读资料不是特别明白,看到一个博主的解释,豁然开朗,特此记录. https://blog.csdn.net/huangzx3/article/details/79347556 DNS区域(ZONE ...
- [Array] 561. Array Partition I
Given an array of 2n integers, your task is to group these integers into n pairs of integer, say (a1 ...
- Django项目:CRM(客户关系管理系统)--32--24PerfectCRM实现King_admin自定义操作数据
#admin.py # ————————01PerfectCRM基本配置ADMIN———————— from django.contrib import admin # Register your m ...