Redis 事务机制
Redis 事务:可以一次执行多个命令,本质是一组命令的集合。一个事务中的所有命令都会序列化,按顺序串行化执行而不会被其它命令插入,一次性、顺序性、排他性的执行一系列命令。
一、常用命令
【1】:开启一个事务
【2】 :执行事务中的命令。可以看到 开始到 之间,所有的命令都会被加入到一个命令队列中。当执行 命令后,将 QUEUED 中所有的命令执行。
【3】:放弃事务
常见的两种状况:①、全体连坐(当语法有错时,一条都不成功)②、冤头债主(当时编译时出错,部分可以成功)
注意事项:Redis 的事务没有提供类似于关系型数据库的回滚(rollback),所以开发人员必须在事务执行失败后进行后续的处理。
每个 Redis 客户端都有自己的事务状态,保存在 multiState 属性中,进一步,每一个事务状态包含一个事务队列以及已入队命令的计数器,事务队列是一个数组,数组中的每个元素保存了已入队命令的相关信息,包含指向命令实现函数的指针、命令的参数,以及参数的数量。
二、WATCH 监控
在 Nosql 数据库中,CAS 是一种保证原子性的操作。Redis 也提供了这样的一个机制,就是利用 Watch命令来实现的。Watch 指令,类似乐观锁(悲观锁:锁整张表。乐观锁:锁一行数据),事务提交时,如果 Key 的值已被别的客户端改变,比如某个 list已被别的客户端 push/pop 过了,整个事务队列都不会被执行,通过 WATCH 命令在事务执行之前监控了多个 Keys,倘若在WATCH 之后有任何 Key 的值发生了变化,EXEC 命令执行的事务都将被放弃,同时返回 Nullmulti-bulk 应答以通知调用者事务执行失败。
【1】客户端1:对 key = redis 的值进行监控,并开启事务后对 key = redis 的数据进行修改。如下:
UNWATCH:取消监控,与 WATCH 命令相反。当指向提交事务EXEC 或取消事务DISCARD 时,会自动执行 UNWATCH 取消客户端对某 key 的监控
三、小结
3 阶段:【1】开启:以MULTI开始一个事务
【2】入队:将多个命令入队到事务中,接到这些命令并不会立即执行,而是放到等待执行的事务队列里面
【3】执行:由EXEC命令触发事务
3 特性:【1】单独的隔离操作:事务中的所有命令都会序列化、按顺序地执行。事务在执行的过程中,不会被其他客户端发送来的命令请求所打断。
【2】没有隔离级别的概念:队列中的命令没有提交之前都不会实际的被执行,因为事务提交前任何指令都不会被实际执行,也就不存在 ”事务内的查询要看到事务里的更新,在事务外查询不能看到” 这个让人万分头痛的问题。
【3】不保证原子性:redis 同一个事务中如果有一条命令执行失败,其后的命令仍然会被执行,没有回滚。