我正在参加「启航方案」

前语

提到业务,咱们想到的都是联系型数据库能完成的。在Redis中,其实也有完成业务的办法。但为什么咱们都说Redis不支持业务呢?那就要提到咱们对业务的要求-ACID了。

业务ACID的要求

咱们都知道,业务包含原子性、共同性、阻隔性、耐久性。 简单解释一下4个特点的意义:

  • 原子性: 一个业务中的多个操作必须都完结,或许都不完结。
  • 共同性:数据在业务履行前后,数据库的完整性没有被损坏。 比方销售前库存+售出的个数是100,销售后加起来的个数也是100.
  • 阻隔性:在履行一个业务时,任何其他操作无法存取到正在履行业务拜访的数据。
  • 耐久性:履行业务后,数据的修正要被耐久化保存下来。当数据库重启后,数据的值需要是被修正后的值。

Redis的业务

Redis可通过MULTIEXEC来完成业务。运用过程很简单:

  1. MULTI来声明敞开一个业务;
  2. 业务敞开后,客户端将要履行的多个操作都发到服务端。但redis不会马上履行,而是放在一个待履行的行列中。
  3. EXEC指令来履行上述的指令。EXEC履行后,行列中的指令才会在Redis中履行。

来个简单比如:

127.0.0.1:6379> MULTI
OK
127.0.0.1:6379> DECR A:num
QUEUED
127.0.0.1:6379> DECR A:num
QUEUED
127.0.0.1:6379> EXEC
1) (integer) -1
2) (integer) -1

从比如中能清晰看到EXEC履行后,两个指令才履行。

Redis的业务能满意ACID的哪些特点要求

原子性

首先来看原子性。MULTI和EXEC合作运用,的确能够确保多个操作都完结。可是咱们要考虑到业务履行假如犯错的状况。 分状况评论:

  • 履行EXEC指令前的过错:客户端发来的指令自身就有过错,比方说语法过错。该状况在EXEC提交后,Redis会拒绝所有的操作。这种状况能确保原子性。
  • 指令入行列的时候,指令和操作的数据类型不符:这种状况Redis由于还没履行指令,查看不到过错。当履行EXEC后才会报错。这种状况不会拒绝其他的操作,不能确保原子性。
  • 履行EXEC指令时,Redis实例毛病:这种状况也会导致业务失败。假如敞开了AOF日志,当AOF康复Redis实例后,业务不会被履行,能确保原子性;但若没有敞开AOF,Redis重启后数据丢掉,也就不能确保原子性。

共同性

再来看共同性。也要分状况来评论:

  • 指令入行列的时候报错: 业务自身都不会履行,能够确保共同性。
  • 指令入行列未报错,实践履行时报错:过错的指令不会履行,但正确的会履行,也不会影响共同性。
  • EXEC指令履行时实例毛病
      1. 假如没有敞开RDB或AOF:数据都丢掉了,没有共同性问题。
      1. 敞开了RDB快照:由于 RDB 快照不会在业务履行时履行,所以,业务指令操作的结果不会被保存到 RDB 快照中,运用 RDB 快照进行康复时,数据库里的数据也是共同的。
      1. 敞开了AOF日志:假如业务操作还没记录到AOF日志,实例就毛病了,那么AOF日志康复的数据是共同的;假如部分操作被记录到AOF日志,咱们能够用redis-check-aof来铲除业务中现已完结的操作,数据康复后也是共同的

阻隔性

业务的阻隔性确保,要考虑到同时进行的业务操作。

  • 其他业务操作在EXEC指令前履行,此刻阻隔性的确保要运用WATCH机制来完成,不然阻隔性无法确保;
  • 其他业务操作在EXEC指令后履行,此刻阻隔性能够确保。由于Redis是单线程履行指令,EXEC指令履行后,Redis会确保先把指令行列的所有指令履行完。因此其他业务操作不会损坏业务的阻隔性。

WATCH机制

一个业务的EXEC指令还没履行,此刻指令还在行列中。此刻假如有其他的并发操作,需要看业务是否运用了WATCH机制。若用了WATCH机制,阻隔性可确保;不然无法确保业务的阻隔性。

WATCH 机制的作用是,在业务履行前,监控一个或多个键的值变化状况,当业务调用 EXEC 指令履行时,WATCH 机制会先查看监控的键是否被其它客户端修正了。假如修正了,就放弃业务履行,避免业务的阻隔性被损坏。然后,客户端能够再次履行业务,此刻,假如没有并发修正业务数据的操作了,业务就能正常履行,阻隔性也得到了确保。

下面是一个watch机制的图例,便利理解它的功用。

redis的事务能保证ACID属性吗

耐久性

最后说说耐久性,耐久性取决于Redis的耐久化装备形式。

假如说都没敞开RDB或许AOF,数据都丢了,业务的耐久性必定得不到确保。

假如你敞开了RDB,一个业务履行后,RDB快照还未履行前,此刻Redis发生宕机,业务修正的数据丢掉了,也不能确保耐久化;

假如你敞开了AOF,由于 AOF 形式的三种装备选项 no、everysec 和 always 都会存在数据丢掉的状况,也不能确保耐久化。

小结

从本文对Redis业务的分析,咱们能知道为什么说Redis不支持业务,是由于它不能确保ACID特点。 假如业务操作需要业务要求,那么能够运用联系型数据库来完成。