1 什么是Redis的事务
在 Redis 中,事务是一组命令的集合,那些在一个事务中的命令会被序列化,会按顺序的串行化执行,不会被事务以外的其他命令插入.在 Redis 中,事务通过 MULTI、EXEC、DISCARD 和 WATCH 这几个命令来实现。
在一个队列中,一次性地,顺序地,排他的执行一系列命令.
2 Redis的事务 和 数据库事务一样吗?
绝对不一样 尤其是原子性这一点 Redis的事务在本质上没有rollback的能力,它只有决定是否开始执行全部指令的能力,没有执行到一半进行回滚的能力。
-
单独的隔离操作:
Redis的事务仅保证事务内的操作会被连续独占执行。Redis命令执行是单线程架构,在执行完事务内所有指令前不可能同时执行其他客户端的请求。
-
没有隔离级别的概念:
因为事务提交前任何指令都不会被实际执行,所以不存在“事务内的查询要看到事务里的更新,而在事务外查询不能看到”这种问题。也就是不存在数据库事务那种脏读 幻读 不可重复读
-
不保证原子性:
Redis的事务不保证原子性,即不保证所有指令同时成功或同时失败。它只有决定是否开始执行全部指令的能力,没有执行到一半进行回滚的能力。
-
排它性:
Redis会保证一个事务内的命令依次执行,而不会被其他命令插入。
3 Redis事务命令汇总
MULTI 标记一个事务块的开始
WATCH key [key ...] 监视一个(或多个)key
EXEC 执行所有事务块内的命令
DISCARD 取消事务,放弃执行事务块内的所有命令
UNWATCH 取消 WATCH 命令对所有 key 的监视
4 Redis事务实战演示
4.1 正常执行
没有出任何错误时,事务正常进行
4.2 放弃事务
使用discard来放弃整个事务
4.3 全体连坐
全体连坐指的是,事务中某条命令根本就没能加入事务中去(常常是因为语法错误等),导致整个事务的命令被全部抛弃
4.4 冤头债主
冤头债主指的是,事务执行后,事务中的某个命令执行时出错了(有点类型java的运行时异常),导致执行出错的语句执行失败,事务内的其他语句可以正常执行
全体连坐 和 冤头债主 证明了 Redis的事务本质上不能保证原子性,没有rollback的能力,全体连坐 表面上看好像是一损俱损,但实际上是 本来就都没执行,只是把事务给抛弃了而已.
4.5 watch监控
watch
redis官方表示 watch是一种乐观锁
- 乐观锁(Optimistic Locking):
乐观锁的基本思想是假设在大多数情况下,数据并发访问冲突的概率较低,因此在读取数据时并不立即加锁,而是在更新数据时再去检查数据是否发生了变化。- 悲观锁(Pessimistic Locking):
悲观锁则是一种较为保守的策略,它在数据操作之前就会对数据进行加锁,以确保在整
个操作过程中数据不会被其他事务修改。
如何取消监控?
使用unwatch命令取消对所有key的监控
一旦执行了exec之前加的监控锁都会被取消掉了
当客户端连接丢失的时候(比如退出链接),所有东西都会被取消监视
watch实战演示
使用 watch key 来监控某个key值是否有变化,如果有变化,则取消本次事务,如下图所示,事务内 对 balance 的set 语句没执行前 在另一个客户端去修改 balance 再回到原客户端执行事务,执行后发现 balance修改失败 k1也修改失败
unwatch
顾名思义,unwatch 表示取消之前所有的对key的监控
一旦取消,执行过程中是不会管 这个数据有没有被更新的 会直接执行写操作
5 Redis总结
开启:
以MULTI开始一个事务
入队:将多个命令入队到事务中,接到这些命令并不会立即执行而是放到等待执行的事务队列里面
执行:由EXEC命令触发事务