Redis设计与实现(一~五整合版)(7)

隔离性(isolation):一个事务的执行不能被其他事务干扰。即一个事务内部的操作及使用的数据对并发的其他事务是隔离的,并发执行的各个事务之间不能互相干扰。

持久性(durability):持续性也称永久性(permanence),指一个事务一旦提交,它对数据库中数据的改变就应该是永久性的。接下来的其他操作或故障不应该对其有任何影响。

那么,redis是通过MULTI/DISCARD/EXEC/WATCH这4个命令来实现事务功能。对事务,我们必须知道事务安全性是一个非常重要的。

事务提供了一种“将多个命令打包,然后一次性、按顺序执行”的机制,并且在事务执行期间不会中断——意思就是在事务完成之前,客户端的其他命令都是阻塞状态。

以下是一个事务的例子,它先以 MULTI 开始一个事务,然后将多个命令入队到事务中,最后 由EXEC 命令触发事务,一并执行事务中的所有命令:

redis> MULTI OK redis> SET book-name "Mastering C++ in 21 days"81 QUEUED redis> GET book-name QUEUED redis> SADD tag "C++" "Programming" "Mastering Series" QUEUED redis> SMEMBERS tag QUEUED redis> EXEC 1) OK 2) "Mastering C++ in 21 days" 3) (integer) 3 4) 1) "Mastering Series" 2) "C++" 3) "Programming"

一个事务主要经历3个阶段:

开始事务

命令入队(看,上面都有QUEUED这个返回值)

执行事务

这几个过程都比较简单,开始事务就是切换到事务模式;命令入队就是把事务中的每条命令记录下来,包括是第几条命令,命令参数什么的(当然,事务中是不能再嵌套事务的,所以再有事务关键字(MULTI/DISCARD/WATCH)会立即执行的);执行事务就是一下子把刚才那个事务的命令执行完。

DISCARD: 取消一个事务,它会清空客户端的整个事务队列,然后将客户端从事务状态调整回非事务状态,最终返回字符串OK给客户端,说明事务已经取消

MULTI:因为redis不允许事务嵌套,所以,当在事务中输入MULTI时,redis服务器会简单返回一个错误,然后继续等待该事务的其他操作,就好像没有输入过MULTI一样

WATCH:WATCH用于在事务开始之前监视任意数量的键,当调用EXEC执行事务时,如果任意一个监视的键被修改了,那么整个事务就不再执行,直接返回失败。【事务安全性检查】

对于上面的WATCH来说,我们可以看成一个锁。这个锁在执行期间是不可以修改(类比为打开锁)的,这样才能保证这次事务是隔离的,安全的。那么,WATCH是如何触发的呢?

在任何对数据库键空间进行修改的命令执行成功后,multi.c/touchWatchKey函数都会被调用——它会检查数据库的watch_keys字典,看是否有客户端在监视被修改的键,如果有的话,就把这个监视的是客户端的REDIS_DIRTY_CAS打开。之后,执行EXEC前,会对这个事务的客户端检查是否REDIS_DIRTY_CAS被打开,打开的话就说明事务的安全性被破坏,直接返回失败;反之则正常进行事务操作。

事务的ACID性质

前面说到,事务一般具有ACID属性,但是redis只保证两种机制:一致性和隔离性。对于原子性和持久性并没有支持,下面说明redis为什么这样做。

原子性:redis的单条命令是原子性的,但是redis没有对事务进行原子性保护。如果一个事务没有执行成功,是不会进行重试或者回滚的。

一致性【redis保证】:这个要分三个层次:

入队错误:如果执行一个错误的命令(比如命令参数不对:set key),那么会被标记为REDIS_DIRTY_EXEC,执行会直接返回错误

执行错误:对某个类型key执行其他类型的操作,不会影响结果,所以不会影响事务的一致性。事务会继续进行

redis进程被冻结:简单来说,redis有持久化功能。但是这个持久化是建立在执行成功的基础上,如果不成功是不会进行持久化的。所以,出问题时都会保证要么事务没有执行;要么事务执行成功。所以保证了数据的一致性。

隔离性【redis保证】:因为redis是单进程程序,并在执行事务时不会中断,一直执行到事务对列为空,所以隔离性是可以保证的。

持久性:不管是单纯的内存模式,还是开启了持久化文件的功能,事务的每条命令执行过程中都会有时间间隙,如果这时候出现问题,持久化还是无法保证。所以,redis使用的是事务没执行或者事务执行完成才会进行持久化工作(AOF模式除外,虽然现在还没有看到- -)

2. 订阅与发布

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/6be4ac5bc3f297e5261a68427fc4282e.html