Redis 事务番外篇

你可能已经注意到「事务」这个词。在学习数据库原理的时候有提到过事务的 ACID,即原子性、一致性、隔离性、持久性。接下来,看看 redis 事务是否支持 ACID。

原子性,即一个事务中的所有操作,要么全部完成,要么全部不完成,不会结束在中间某个环节。redis 事务不支持原子性,最明显的是 redis 不支持回滚操作。

一致性,在事务开始之前和事务结束以后,数据库的完整性没有被破坏。这一点,redis 事务能够保证。

隔离性,当两个或者多个事务并发访问(此处访问指查询和修改的操作)数据库的同一数据时所表现出的相互关系。redis 不存在多个事务的问题,因为 redis 是单进程单线程的工作模式。

持久性,在事务完成以后,该事务对数据库所作的更改便持久地保存在数据库之中,并且是完全的。redis 提供两种持久化的方式,即 RDB 和 AOF。RDB 持久化只备份当前内存中的数据集,事务执行完毕时,其数据还在内存中,并未立即写入到磁盘,所以 RDB 持久化不能保证 redis 事务的持久性。再来讨论 AOF 持久化,我在《深入剖析 redis AOF 持久化策略》中讨论过:redis AOF 有后台执行和边服务边备份两种方式。后台执行和 RDB 持久化类似,只能保存当前内存中的数据集;边备份边服务的方式中,因为 redis 只是每间隔 2s 才进行一次备份,因此它的持久性也是不完整的!

当然,我们可以自己修改源码保证 redis 事务的持久性,这不难。

还有一个亮点,就是 check-and-set CAS。一个修改操作不断的判断 X 值是否已经被修改,直到 X 值没有被其他操作修改,才设置新的值。redis 借助 WATCH/MULTI 命令来实现 CAS 操作的。

实际操作中,多个线程尝试修改一个全局变量,通常我们会用锁,从读取这个变量的时候就开始锁住这个资源从而阻挡其他线程的修改,修改完毕后才释放锁,这是悲观锁的做法。相对应的有一种乐观锁,乐观锁假定其他用户企图修改你正在修改的对象的概率很小,直到提交变更的时候才加锁,读取和修改的情况都不加锁。一般情况下,不同客户端会访问修改不同的键值对,因此一般 check 一次就可以 set 了,而不需要重复 check 多次。

results matching ""

    No results matching ""