Redis 事务提供了一种将多个命令请求打包,然后一次性、按顺序地执行多个命令的机制,并且在事务执行期间,服务器不会中断,会将事务中的所以命令都执行完毕才去处理其他客户端的命令请求。

事务的实现

事务开始

MULTI 命令意味着事务的开始。

事务从开始到结束包含三个阶段:事务开始、命令入队、事务执行。

127.0.0.1:6379> multi
OK

multi 命令将执行命令的客户端从非事务切换到事务状态,这一切换是通过在客户端状态的 flags 属性中打开 REDIS_MULTI 标识完成的。返回客户端 OK。

命令入队

在事务状态中,服务器会立刻执行 exec、discard、watch、multi 四个命令中的一个,而非这些命令将会放入事务事务队列,然后返回 QUEUED。

事务队列

每个 Redis 客户端都有自己的事务状态,这个事务状态保存在客户端状态的 mstate 属性里:

typedef struct redisClient {
// ...
multiState mstate; /* MULTI/EXEC state */
// ...
} typedef struct multiState {
multiCmd *commands; /* Array of MULTI commands */
int count; /* Total number of MULTI commands */
int minreplicas; /* MINREPLICAS for synchronous replication */
time_t minreplicas_timeout; /* MINREPLICAS timeout as unixtime. */
} multiState; /* Client MULTI/EXEC state */
typedef struct multiCmd {
robj **argv;
int argc;
struct redisComm,and *cmd;
} multiCmd;

执行事务

当一个处于事务状态的客户端向服务器发送 exec 命令时,这个 exec 命令将立刻被服务器执行,遍历事务队列执行所有命令,最后将执行命令所得的结果全部返回给客户端。

watch 命令的实现

watch 命令是个乐观锁,它可以在 exec 命令执行前,监视任意数量的数据库键。当发现有修改则拒绝事务执行并向客户端返回代表事务执行失败的空回复。

使用 watch 命令监视数据库键

每个 Redis 数据库都保存着一个 watched_keys 字典,键是被 watch 命令监视的数据库键,字典值是所有监视这个键的客户端链表。

监视机制的触发

所有对于数据库进行修改的命令执行后都会调用 multi.c/touchWatchKey 函数对 watched_keys 字典进行检查,如果有客户端正在监视刚刚被命令修改过的数据库键,touchWatchKey 函数会将监视被修改键的客户端的 REDIS_DIRTY_CAS 标识打开,表示客户端的事务安全性被破坏。

判断事务是否安全

当服务器收到客户端发来的 exec 命令时,服务器会根据这个客户端是否打开了 REDIS_DIRTY_CAS 标识来决定是否执行事务。

事务的 ACID 性质

A:Atomicity,原子性;

C:Consistency,一致性;

I:Isolation,隔离性;

D:Durability,耐久性。

原子性

原子性是指将事务中的多个操作作为一个整体来执行,要么全部执行成功,要么一个都不执行。Redis 不支持事务回滚机制,即使事务队列中的某个命令在执行期间出现了错误,整个事务也会继续执行下去,直到将事务队列中的所有命令都执行完毕为止。

一致性

如果数据库在执行事务之前是一致的,那么在事务执行之后无论事务是否执行成功,数据库应该是一致的。一致是指数据符合数据库本身的定义和要求,没有包含非法或者无效的错误数据。

隔离性

即使数据库有多个事务并发地执行,各个事务之间也不会互相影响,并发和串行状态事务产生的结果完全相同。

耐久性

当一个事务执行完毕时,执行这个事务所得到的结果已经被保存到永久存储介质里,即使事务执行完毕后停机,执行事务的结果也不会丢失。

Redis学习笔记五:独立功能之事务的更多相关文章

  1. Redis学习笔记--五种数据类型的使用场景

    String 1.String 常用命令: 除了get.set.incr.decr mget等操作外,Redis还提供了下面一些操作: 获取字符串长度 往字符串append内容 设置和获取字符串的某一 ...

  2. Redis学习笔记(二十一) 事务

    文章开始啰嗦两句,写到这里共21篇关于redis的琐碎知识,没有过多的写编程过程中redis的应用,着重写的是redis命令.客户端.服务器以及生产环境搭建用到的主从.哨兵.集群实现原理,如果你真的能 ...

  3. Redis 学习笔记五 经常使用php函数

    PHPRedis的安装在这里: http://blog.csdn.net/xundh/article/details/46288277 键值操作 $redis = new Redis(); $redi ...

  4. StackExchange.Redis学习笔记(五) 发布和订阅

    Redis命令中的Pub/Sub Redis在 2.0之后的版本中 实现了 事件推送的  发布订阅命令 以下是Redis关于发布和订阅提供的相关命令 SUBSCRIBE channel [channe ...

  5. Spring学习笔记五:Spring进行事务管理

    转载请注明原文地址:http://www.cnblogs.com/ygj0930/p/6776256.html  事务管理主要负责对持久化方法进行统一的提交或回滚,Spring进行事务管理即我们无需在 ...

  6. redis 学习笔记(6)-cluster集群搭建

    上次写redis的学习笔记还是2014年,一转眼已经快2年过去了,在段时间里,redis最大的变化之一就是cluster功能的正式发布,以前要搞redis集群,得借助一致性hash来自己搞shardi ...

  7. (转)redis 学习笔记(1)-编译、启动、停止

    redis 学习笔记(1)-编译.启动.停止   一.下载.编译 redis是以源码方式发行的,先下载源码,然后在linux下编译 1.1 http://www.redis.io/download 先 ...

  8. Redis学习笔记~目录

    回到占占推荐博客索引 百度百科 redis是一个key-value存储系统.和Memcached类似,它支持存储的value类型相对更多,包括string(字符串).list(链表).set(集合). ...

  9. Redis学习笔记4-Redis配置详解

    在Redis中直接启动redis-server服务时, 采用的是默认的配置文件.采用redis-server   xxx.conf 这样的方式可以按照指定的配置文件来运行Redis服务.按照本Redi ...

随机推荐

  1. JPA mysql wildfly jboss 存储时乱码

    首先确保mysql的库,表创建时指定的字符集collation. 可以直接用命令行插入中文,看查询出来是不是中文. insert into live_main_sync (cn_name, creat ...

  2. linux 基础 shell脚本命令

    #########shell脚本命令#### 1.diff diff file file1 ####比较两个文件的不同 -c ####显示周围的行 -u ####按照一格式统一输出生成补丁 -r ## ...

  3. [转发]Linux的系统调用宏

    原来在linux/include/linux/syscalls.h 中定义了如下的宏: 复制代码#define SYSCALL_DEFINE1(name, ...) SYSCALL_DEFINEx(1 ...

  4. css3实现小黄人

    效果就像这样: 不废话,直接上代码! hrml代码: <!DOCTYPE html> <html> <head lang="zh"> <m ...

  5. python类相关

    class A: def bar(self): print("BAR") self.f1() class B(A): def f1(self): print("B&quo ...

  6. pc端,自适应屏幕分辨率

    前端开发框架Bootstrap  网址:http://www.dnzs.com.cn/w3cschool/bootstrap/bootstrap-tutorial.html 需要加入代码 <sc ...

  7. How to get http response.

    public class HttpWebResponseUtility { public static string CreateGetHttpResponse(string url) { var r ...

  8. Unity中各个平台的预编译的运用方式

    1,unity中官方文档的一个操纵关键词   Platform Dependent Compilation 2,常用的预编译关键词    UNITY_EDITOR    编辑器调用.UNITY_STA ...

  9. http的六种请求方法

    1.get: GET可以说是最常见的了,它本质就是发送一个请求来取得服务器上的某一资源.资源通过一组HTTP头和呈现数据(如HTML文本,或者图片或者视频等)返回给客户端.GET请求中,永远不会包含呈 ...

  10. Orchard源码分析(4.4):Orchard.Caching.CacheModule类

    概述 CacheModule也是一个Autofac模块.   一.CacheModule类 CacheModule将DefaultCacheManager注册为ICacheManager:       ...