Redis入门(六)——Redis事务mysql
目录:redis
1.redis事务简介sql
事务指的是能够一次执行多个命令,本质是一组命令集合,一个事务中的全部命令都会序列化,按顺序的串行化执行而不会被其余命令插入。银行转帐就是最经典的事务场景之一。数据库
redis事务用于一个队列中,一次性,顺序性。排他性的执行一系列命令。服务器
传统的关系型数据库如mysql,oracle中的事务须要知足ACID四个特性。即:网络
原子性(atomicity):事务是数据库的逻辑工做单位,并且是必须是原子工做单位,对于其数据修改,要么所有执行,要么所有不执行。
一致性(consistency):事务在完成时,必须是全部的数据都保持一致状态。在相关数据库中,全部规则都必须应用于事务的修改,以保持全部数据的完整性。
隔离性(isolation):一个事务的执行不能被其余事务所影响。oracle
持久性(durability):一个事务一旦提交,事物的操做便永久性的保存在DB中。即使是在数据库系统遇到故障的状况下也不会丢失提交事务的操做。
分布式
而redis数据属于典型的Nosql数据库。不须要知足ACID四个特性。Nosql数据库知足CAP三个特性其中之二。CAP即:atom
强一致性(Consistency):在任意时刻,全部的分布式节点中的数据是同样的。spa
可用性(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应答已通知调用者事务执行失败。