Redis入门(六)——Redis事务
目录:
1.redis事务简介
事务指的是可以一次执行多个命令,本质是一组命令集合,一个事务中的所有命令都会序列化,按顺序的串行化执行而不会被其他命令插入。银行转账就是最经典的事务场景之一。
redis事务用于一个队列中,一次性,顺序性。排他性的执行一系列命令。
传统的关系型数据库如mysql,oracle中的事务需要满足ACID四个特性。即:
原子性(atomicity):事务是数据库的逻辑工作单位,而且是必须是原子工作单位,对于其数据修改,要么全部执行,要么全部不执行。
一致性(consistency):事务在完成时,必须是所有的数据都保持一致状态。在相关数据库中,所有规则都必须应用于事务的修改,以保持所有数据的完整性。
隔离性(isolation):一个事务的执行不能被其他事务所影响。
持久性(durability):一个事务一旦提交,事物的操作便永久性的保存在DB中。即便是在数据库系统遇到故障的情况下也不会丢失提交事务的操作。
而redis数据属于典型的Nosql数据库。不需要满足ACID四个特性。Nosql数据库满足CAP三个特性其中之二。CAP即:
强一致性(Consistency):在任意时刻,所有的分布式节点中的数据是一样的。
可用性(Availability):分布式系统中某一个服务在某台或者多台台服务器出问题后,在其他服务器上依然能够完成用户的操作。
分区容错性(Partition torerance):在出现网络分区(比如断网)的情况下,分离的系统也能正常运行。
2.redis事务使用
下表列出了 redis 事务的相关命令:
命令 | 描述 | 用法 |
MULTI | 标记一个事务块的开始 |
MULTI 标记一个事务开始,后面是一系列事务操作。 |
EXEC | 执行所有事务块内的命令 |
EXEC 在一系列事务操作后使用该命令,执行所有事务块内的命令。 |
DISCARD | 取消事务,放弃执行事务块内的所有命令 |
DISCARD 在一系列事务操作后使用该命令,放弃执行事务块内的所有命令 |
WATCH | 监视一个(或多个) key ,如果在事务执行之前这个(或这些) key 被其他命令所改动,那么事务将被打断。 |
WATCH key [key ...] |
UNWATCH | 取消 WATCH 命令对所有 key 的监视。 | UNWATCH |
MULTI命令实例:
只要符合redis语法规范的命令均可入队。
放弃事务实例:
事务执行失败实例:
当事务中有一个命令执行失败,其他命令会执行成功吗?下图为实际操作的实例:
可见,redis事务中要么全部执行成功,要么全部执行失败。可是前文不是说不满足原子性吗,这里岂不是满足原子性。上图中出现了我胡乱加的一个命令abc k7 v7,也就是说该命令不满足redis语法规范。那如果是满足redis语法规范的语句,在redis事务中执行失败,其他合法命令会怎么样呢?下图演示了该场景下的操作情况。
其中,k1是一个string类型的数据,执行incr命令会不通过,但是由于符合语法规范,该语句不会报错,仍然显示加入队列中。当我们执行EXEC命令来执行整个事务的时候后,可见incr k1执行失败,而其他可以执行的语句并不受影响。可见redis事务不满足原子性。
WATCH监控:
在介绍WATCH命令之前先说明下redis中的乐观锁悲观锁的概念以及CAS。
悲观锁:每次器拿数据的时候都认为该数据会被修改,所以每次拿到数据后都会对该数据上锁,保证自由自己操作该数据。等本次获取的锁释放后其他操作方可获得该锁。
乐观锁:每次器拿数据的时候都认为该数据不会被修改,所以不会上锁,但是下更新该数据的时候回判断下别人有没有更新该数据,通常使用版本号的机制。即每次修改数据后对该数据价格版本号,其他人在修改该数据前先对比下该数据的版本号有没有变化。一般实际场景中使用的是乐观锁。
下面以信用卡可用余额与欠额的场景说明WATCH的应用。
首先来看没有加塞的场景,WATCH balance,然后在一个事务中减少balance增加debt,执行EXEC命令后,可见事务执行成功。
再来看有加塞的场景,首先还是WATCH balance,然后另外开启一个redis连接。修改balance的值,再回到第一个redis连接上,执行之前的事务操作,该事务操作是否会执行成功,请看下面的操作实例
UNWATCH命令:
执行UNWATCH,取消 WATCH 命令对所有 key 的监控。注意,一旦执行了EXEC命令,之前加的监控锁都会被取消。
3.小结
WATCH指令类似于乐观锁,事务提交时,如果key的值已经被别的客户改变,比如某个list已被别的客户端push/pop过了,整个事务都不会被执行。
通过WATCH命令在事务执行之前监控了多个key,倘若在WATCH之后有任何key的值发生变化,EXEC命令执行的事务都将被放弃,同时返回Nullmuti-bulk应答已通知调用者事务执行失败。
原文:https://www.cnblogs.com/zylhxd/p/11439247.html