欢迎访问悦橙教程(wld5.com),关注java教程。悦橙教程  java问答|  每日更新
页面导航 : > > 文章正文

Redis事务的实现原理,

来源: javaer 分享于  点击 48772 次 点评:258

Redis事务的实现原理,


Redis通过MULTIEXECWATCHDISCARD等命令来实现事务功能。主要有以下三个阶段:

事务开始

MULTI命令的执行,标识着一个事务的开始。MULTI命令会将客户端状态的flags属性中打开REDIS_MULTI标识来完成的。

命令入队

当一个客户端切换到事务状态之后,服务器会根据这个客户端发送来的命令来执行不同的操作。如果客户端发送的命令为MULTIEXECWATCHDISCARD中的一个,立即执行这个命令,否则将命令放入一个事务队列里面,然后向客户端返回QUEUED回复

  • Redis客户端拥有自己的事务状态
typedef struct client {
    // ......
    // 事务状态(MULTI或者EXEC)
    multiState mstate;
    // ......
} client;
  • 事务状态包含一个事务队列
typedef struct multiState {
    // 事务队列,FIFO
    multiCmd *commands;
    // 已入队命令计数
    int count;
    // ......
} multiState;
  • 事务队列中multiCmd类型保存了一个已入队命令的相关信息
typedef struct multiCmd {
    // 参数
    robj **argv;
    // 参数数量
    int argc;
    // 命令指针
    struct redisCommand *cmd;
} multiCmd;

事务队列是按照FIFO的方式保存入队的命令

事务执行

当一个处于事务状态的客户端向服务器发送EXEC命令时,服务器会遍历这个客户端的事务队列,执行队列中保存的所有命令,最后将执行完的结果全部返回给客户端(每个命令对应一个返回)

WATCH命令的实现

WATCH命令是一个乐观锁,它可以在EXEC命令执行之前,监视任意数量的数据库键,并在执行EXEC命令时,检查被监视的键是否至少有一个已经被修改,如果有,服务器拒绝执行事务,向客户端返回代表事务执行失败的空回复

实现原理
typedef struct redisDb {
    //  ......
    //  正在被WATCH命令监视的键
    dict *watched_keys;
    //  ......
} redisDb;
  1. 监视机制的触发:所有对数据库进行修改的命令,在执行之后都会调用touchWatchKey函数对watched_keys字典进行检查,如果有客户端监视的key被修改过,那么touchWatchKey函数会将监视被修改的客户端的REDIS_DIRTY_CAS标识打开,表示事务已经被破坏
  2. 判断事务是否安全:如果客户端的REDIS_DIRTY_CAS标识被打开了,说明客户端提交的事务已经不再安全,所以服务器会拒绝执行客户端提交的事务

事务的ACID性质

  • 原子性:对于Redis的事务功能来说,事务队列中的命令要么就全部执行,要么就一个都不执行,但是Redis的事务是不支持回滚操作的

  • 一致性:Redis通过谨慎的错误检测和简单的设计保证事务的一致性。Redis事务可能出错的地方以及解决方案:

  • 隔离性:Redis使用单线程的方式执行事务,并且服务器保证在执行事务期间不会对事务进行中断,因此,Redis的事务总是串行的方式运行,并且事务总是具有隔离性的

  • 耐久性:当服务器运行在AOF持久化模式下,并且appendfsync选项的值是always时,事务是具有耐久性的,其他情况不具有耐久性

相关文章

    暂无相关文章
相关栏目:

用户点评