Redis事务

12 篇文章 4 订阅

        事务同命令一样,都是Redis的最小执行单位,一个事务中的命令要么都执行,要么都不执行。

一、Redis事务的实现

        Redis通过multi、exec、watch等命令来实现事务功能,Redis中一个事务从开始到结束包含三个阶段:事务开始、命令入队、事务执行。其中multi命令标志着事务开始,exec命令标志着事务执行,期间所有命令都会存放到事务队列中。

在redis.h/redisClient结构中,可以看到每个Redis客户端都有自己的事务状态,保存在multiState属性中

typedef struct redisClient{
    //...
    // 事务状态
    multiState mstate;      /* MULTI/EXEC state */
    //...
}

在redis.h/multiState结构可以看到其包含一个事务队列multiCmd以及一个已入队的命令计数器

/*
 * 事务状态
 */
typedef struct multiState {
    // 事务队列,FIFO 顺序
    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;

在redis.h/multiCmd结构中可以看到已入队的命令的相关信息,包括指向命令实现函数的指针、命令参数及参数数量

/*
 * 事务命令
 */
typedef struct multiCmd {
    // 参数
    robj **argv;
    // 参数数量
    int argc;
    // 命令指针
    struct redisCommand *cmd;
} multiCmd;

执行如下所示的事务命令

其事务状态如图所示

 

二、Redis事务的特性

        与传统的数据库一样,Redis通过ACID性质来检验事务功能的可靠性和安全性。

1、原子性(Atomicity)

        针对原子性,Redis不支持事务的回滚:

(1)事务要么都执行,要么都不执行;

(2)事务执行失败,后面的命令还会执行,错误之前的命令不回滚;

        针对(1)给出如下图所示的示例,命令在放入事务队列的时候被检测到错误,所以事务中的所有命令都不会执行。在EXEC的时候发现事务错误,事务里的命令都不会执行。因此,谈不到回滚。

        针对(2)给出如下图所示的示例,作者指出不支持事务的回滚是因为这种复杂的功能和Redis追求的简单高效的设计主旨不符合,这种错误通常是由编程错误造成,只会出现在开发环境,不会出现在生产环境中。因此,没有必要开发回滚功能。

2、一致性(Consistency)

        针对一致性,通过妥善处理可能出错的地方,确保事务的一致性:

(1)入队错误:命令入队过程中出现命令不存在或者命令格式不正确的情况,则拒绝执行这个事务;

(2)执行错误:事务在执行过程中出错的命令由相应的错误处理,所以这些出错的命令不会对数据库做任何修改,也不会影响一致性;

(3)服务器停机:
       a)无持久化的内存模式下,重启后空白,一致;
       b)RDB模式下,事务中途停机,重启后可根据RDB文件还原数据库状态;
       c)AOF模式下可根据AOF文件还原数据库状态;

3、隔离性(Isolation)

        针对隔离性,Redis以单线程的方式来执行事务,并保证事务执行期间不会被中断。

4、持久性(Durability)

        针对持久性,Redis的事务是用队列包裹起来的,因此事务的持久性由Redis使用的模式决定,如在AOF模式的事务具有持久性。但不管Redis在什么模式下,在事务的最后加下SAVE命令总可以保证事务的持久性。

 

参考资料

1、http://www.redis.net.cn/tutorial/3506.html
2、《Redis设计与实现》第二版---黄健宏
3、https://github.com/xingzhexiaozhu/redis-3.0-annotated
4、http://www.yiibai.com/redis/redis_strings.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值