欧博allbet网址:Redis系列(九):Redis的事务机制

admin 2个月前 (08-30) 科技 30 0

提到事务,信赖人人都不生疏,事务的ACID四大特征,也是面试时经常问的,不外一样平常情形下,我们可能想到的是传统关系型数据库的事务,实在,Redis也是提供了事务机制的,本篇博客就来讲解下Redis的事务机制。

1. 事务演示

Redis的事务提供了一种将多个下令请求打包,然后一次性、按顺序性地执行多个下令的机制。

在事务执行时代,服务器不会中止事务而去执行其它客户端的下令请求,它会将事务中的所有下令执行完毕,然后才去处置其它客户端的下令请求。

下图展示了一个Redis事务的执行历程:

可以看出,事务以MULTI下令最先,然后将多个下令放到事务当中,最后由EXEC下令将这个事务提交给服务器执行。

2. 事务实现原理

一个事务从最先到竣事会履历以下3个阶段:

  1. 事务最先
  2. 下令入队
  3. 事务执行

2.1 事务最先

MULTI下令的执行标志着事务的最先。

执行完该下令后,客户端状态的flags属性会打开REDIS_MULTI标识,示意该客户端从非事务状态切换至事务状态。

2.2 下令入队

当一个客户端处于非事务状态时,这个客户端发送的下令会立刻被服务器执行:

当一个客户端处于事务状态时,这个客户端发送的下令,服务器是否会立刻执行,分为以下2种情形:

  1. 若是客户端发送的下令为MULTIEXECWATCHDISCARD四个下令中的其中1个,服务器会立刻执行这个下令。
  2. 若是客户端发送的下令为以上4个下令外的其它下令,服务器不会立刻执行这个下令,而是将其放到事务行列里,然后向客户端返回QUEUED回复。

欧博allbet网址:Redis系列(九):Redis的事务机制 第1张

以上流程可以使用以下流程图来示意:

欧博allbet网址:Redis系列(九):Redis的事务机制 第2张

这里首先提下DISCARD下令,这个下令用于作废事务,放弃执行事务块内的所有下令,如下所示:

欧博allbet网址:Redis系列(九):Redis的事务机制 第3张

然后提下事务行列,每个Redis客户端都有自己的事务状态,事务状态存储在客户端状态的mstates属性里:

欧博allbet网址:Redis系列(九):Redis的事务机制 第4张

事务状态包罗1个事务行列和1个已入队下令的数目,如下所示:

欧博allbet网址:Redis系列(九):Redis的事务机制 第5张

事务行列是一个multiCmd类型的数组,数组中的每个multiCmd结构保留了一个已入队下令的相关信息,好比:

  1. 指向下令实现函数的指针,如GET下令、SET下令
  2. 下令的参数
  3. 参数的数目

事务行列以先进先出(FIFO)的方式保留入队的下令。

2.3 事务执行

当一个处于事务状态的客户端执行EXEC下令时,服务器会遍历这个客户端的事务行列,执行行列中保留的所有下令(按先入先出顺序),然后将执行下令的效果一次性返回给客户端。

欧博allbet网址:Redis系列(九):Redis的事务机制 第6张

3. WATCH下令的实现原理

WATCH下令用于监视随便数目的数据库键,并在EXEC下令执行时,检测被监视的键是否被修改,若是被修改了,服务器将拒绝执行事务,并向客户端返回空回复。

为了更好的明白,我们做个演示,首先,我们打开客户端1,执行WATCH下令监视键“name”,然后开启一个事务:

欧博allbet网址:Redis系列(九):Redis的事务机制 第7张

此时,先不要执行EXEC下令,打开客户端2,执行以下下令修改“name”键的值:

欧博allbet网址:Redis系列(九):Redis的事务机制 第8张

然后,在客户端1执行EXEC下令时,会返回空回复,由于“name”键的值在客户端2已经被修改:

欧博allbet网址:Redis系列(九):Redis的事务机制 第9张

那么,WATCH下令的实现原理是什么样的呢?我们从以下3个方面来剖析:

  1. 使用WATCH下令监视数据库键
  2. 监视机制的触发
  3. 判断事务是否平安

3.1 使用WATCH下令监视数据库键

每个Redis数据库都保留着1个watched_keys字典,这个字典的键是某个被WATCH下令监视的数据库键,字典的值是一个链表,链表中记录了所有监视响应数据库键的客户端。

欧博allbet网址:Redis系列(九):Redis的事务机制 第10张

举个例子,如果客户端1正在监视键“name”,客户端2正在监视键“age”,那么watched_keys字典存储的数据也许如下:

欧博allbet网址:Redis系列(九):Redis的事务机制 第11张

若是此时客户端3执行了以下WATCH下令:

欧博allbet网址:Redis系列(九):Redis的事务机制 第12张

那么watched_keys字典存储的数据就变为:

欧博allbet网址:Redis系列(九):Redis的事务机制 第13张

3.2 监视机制的触发

那么问题来了,既然watched_keys字典存储了被WATCH下令监视的键,那么监视机制是若何被触发的呢?

谜底是所有对数据库修改的下令,好比SETLPUSHSADD等,在执行之后都会对watched_keys字典进行检查,若是有客户端正在监视刚刚被下令修改的键,那么所有监视该键的客户端的REDIS_DIRTY_CAS标识将被打开,示意该客户端的事务平安性已经被损坏。

以上图为例,若是键“name”的值被修改,那么客户端1、客户端3的REDIS_DIRTY_CAS标识会被打开。

3.3 判断事务是否平安

最后异常要害的一步是,当服务器接收到一个客户端发来的EXEC下令时,服务器会凭据这个客户端是否打开了REDIS_DIRTY_CAS标识来决议是否执行事务,判断的流程图如下所示:

欧博allbet网址:Redis系列(九):Redis的事务机制 第14张

4. 事务执行失败举例

先来看第1个例子,这个事务由于下令入队失足被服务器拒绝执行,事务中的所有下令都不会被执行:

欧博allbet网址:Redis系列(九):Redis的事务机制 第15张

再来看第2个例子,事务入队时泛起了不存在的下令,服务器将拒绝执行这个事务:

欧博allbet网址:Redis系列(九):Redis的事务机制 第16张

再来看第3个例子,RPUSH下令在执行时代报错了,但后续下令仍然继续执行,而且之前执行的下令没有受到任何影响:

欧博allbet网址:Redis系列(九):Redis的事务机制 第17张

这个例子也说明Redis事务不支持回滚机制

5. 总结

Redis的事务提供了一种将多个下令打包,然后一次性、有序地执行的机制,

它的原理是多个下令会被入队到事务行列中,然后按先进先出(FIFO)的顺序执行,

而且事务在执行历程中不会被中止,当事务行列中的所有下令都被执行完毕之后,事务才会竣事。

6. 参考

黄健宏 《Redis设计与实现》

,

www.px111.net

欢迎进入平心在线官网(原诚信在线、阳光在线)。平心在线官网www.px111.net开放平心在线会员登录网址、平心在线代理后台网址、平心在线APP下载、平心在线电脑客户端下载、平心在线企业邮局等业务。

Sunbet声明:该文看法仅代表作者自己,与本平台无关。转载请注明:欧博allbet网址:Redis系列(九):Redis的事务机制

网友评论

  • (*)

最新评论

标签列表

    文章归档

      站点信息

      • 文章总数:649
      • 页面总数:0
      • 分类总数:8
      • 标签总数:1018
      • 评论总数:288
      • 浏览总数:11727