Redis快速入门(二)之事务

前言:本文为学习Redis总结之用。主要学习路径为官方文档(4.0.10),文中会夹杂官方概念及个人自身见解。

Redis事务简介:

    Redis的事务可以一次执行多个命令并且事务跟事务之间是隔离的单独的操作,一个事务中的所有命令都会序列化,按顺序的执行。事务的执行过程中不会被其他客户端发送过来的命令打断。此外事务是一个原子操作,要嘛全部执行,要嘛不执行。这是官方文档中提到的,但是根据实际的情况来看,Redis的事务针对EXEC执行前后分为了两种情况:

如果EXEC执行前对于语法错误(参数数量错误,参数名错误,等等),或者其他更严重的错误,比如内存不足(如果服务器使用 maxmemory 设置了最大内存限制的话)等情况事务中的命令会全部不执行。

但如果是在EXEC执行后,例如事务中的命令可能处理了错误类型的键,比如将列表命令用在了字符串键上面,诸如此类。错误的命令不执行,正确的命令会正常执行。这样来看是无法保证原子性的。

所以按照我个人理解来说这边存在歧义,此外Redis不支持事务的回滚。

Redis事务命令:

    Redis提供了5个命令来针对事务的使用。

    DISCARD:停止当前事务块,取消事务块中的所有命令。如果使用了WATCH,DISCARD会释放被WATCH的key。

    EXEC:执行当前事务块内的所有命令。如果使用了WATCH,只有当被WATCH的key在事务执行之前没有被修改才会执行。

    MULTI:标记一个事务块的开始。

    WATCH:监视一个或者多个key。

    UNWATCH:取消WATCH命令中监视的key。执行EXEC或者DISCARD会自动取消。

 Redis事务的使用:  

    下面将从4个方面来演示Redis的事务:

    事务正常执行:

   

    事务停止执行:

   

    事务执行出错全部不执行:

   

    事务中错误的不执行,正确的执行:

   

Redis事务的CAS:

    针对并发情况,Redis使用了CAS(check-and-set)操作来实现乐观锁而CAS操作通过WATCH以及UNWATCH来实现(有点类似于version乐观锁)。大致的过程如下:通过WATCH监视指定的key,一旦被监视的这些key在事务执行EXEC前被修改了,那么整个事务都会被取消并返回nil。此外不管事务是否成功一旦执行了EXEC那么被监视的所有key都会取消即UNWATCH。当然我们也可以通过手动使用UNWATCH命令来取消key的监视。例如对于一些需要改动多个键的事务, 有时候程序需要同时对多个键进行加锁, 然后检查这些键的当前值是否符合程序的要求。 当值达不到要求时, 就可以使用 UNWATCH 命令来取消目前对键的监视, 中途放弃这个事务, 并等待事务的下次尝试。

    下面举一个简单的银行账户栗子来演示CAS:

    首先我们设置了一个银行账户,里面有500。在A中我们准备往账户存入100,在开始事务之前我们WATCH监视了账户count以防止有人在这个过程中操作它。接着在A中开启了事务准备进行添加操作,但是在事务EXEC前B中减少了账户100,此时账户变成了400。由于在A开启的事务中一开始监视的时候账户有500跟当前的余额不匹配。因此A事务执行EXEC后返回了nil。说明了事务执行失败。

   

    下面针对当前这个例子介绍下UNWATCH的简单用法。当前在A中仍然注册了一个账户里面有500,接着要进行添加操作,所以使用WATCH来进行监视防止执行事务中被修改。此时B对count进行了添加操作,这个时候在客户端执行事务前中通过get count发现金额已经改变。那么通过手动UNWATCH取消先前对count的监视,重新开启一个新的监视WATCH。此时再开启事务来执行。可以看到这个过程中如果B没有在进行账户操作,那么A中的事务就可以正常执行了。


猜你喜欢

转载自blog.csdn.net/u010890358/article/details/80765914
今日推荐