前言
写博客是自己对知识梳理,目前是写给自己看,算是自己学习后的作业,也是为了养成一个良好的习惯。
一、redis事务简介
1. 什么是事务?
事务ACID,包括原子性、隔离性、持久性和一致性。(具体会在mysql事务中详细说明,这里就默认都知道了)
2. 什么是redis事务?
Redis 事务的本质是一组命令的集合。事务支持一次执行多个命令,一个事务中所有命令都会被序列化。
在事务执行过程,会按照顺序串行化执行队列中的命令,其他客户端提交的命令请求不会插入到事务执行命令序列中。
二、执行过程
1. 开始事务
MULTI命令的执行标记着事务的开始:这个命令唯一做的就是, 将客户端的REDIS_MULTI选项打开,
让客户端从非事务状态切换到事务状态。
2. 命令入队
当客户端进入事务状态之后, 服务器在收到来自客户端的命令时,不会立即执行命令,而是将这些命令全部放进一个事务队列里,然后返回QUEUED,表示命令已入队。
3. 执行事务
EXEC命令的执行就会开始执行队列中的指令。
4. 具体如下图所示:
三、相关指令
1. MULTI
开启事务,redis进入事务状态。
它只能检查入队时错误的命令,如果队列中有错误命令(如 sett k3 v3)就报错(ERR unknown command),事务状态不会解除。
2. EXEC
执行事务,在一个事务中执行所有先前放入队列的命令,然后恢复正常的连接状态。
它不支持回滚,队列中指令执行结果错误也不会终止执行,它仍会顺序执行队列中其他指令。
队列中有错误指令,执行时会报错不执行它之后的指令,并清除事务状态。
3. DISCARD
丢弃事务,清除所有先前在一个事务中放入队列的命令,然后恢复正常的连接状态。
4. WATCH
WATCH 监视一个(或多个) key ,如果在事务执行之前这个(或这些) key 被其他命令所改动,那么事务将被打断。
watch指令类似于乐观锁,在事务提交时,如果watch监控的多个KEY中任何KEY的值已经被其他客户端更改,则使用EXEC执行事务时,
事务队列将不会被执行,同时返回Nullmulti-bulk应答以通知调用者事务执行失败。
具体看下图:
总结
1. redis事务本质上就是一次性、顺序性、排他性的执行一个队列中的一系列命令;
2. redis事务支持隔离性
redis事务执行时队列中的指令不会被插队或中断,且redis事务在EXEC之执行前,批量指令都是缓存在队列中根本就没有执行,
则redis事务之间也都是不可见,即它没有隔离级别(区别于传统关系型数据库的隔离性)。
3. redis事务不支持原子性
单条命令是原子性执行的,但redis事务不保证原子性,且没有回滚。事务中任意命令执行失败,其余的命令仍会被执行。