Redis-事务
1.事务的定义
百度百科:数据库事务( transaction)是访问并可能操作各种数据项的一个数据库操作序列,这些操作要么全部执行,要么全部不执行,是一个不可分割的工作单位。事务由事务开始与事务结束之间执行的全部数据库操作组成。
作者理解:事务是将多条命令放到一起执行,要么都执行,要么都不执行。事务的执行要保证四大特性:原子性,一致性,隔离性,持久性。
2.Redis事务的特性
- 原子性:Redis的原子性只能保证事务中的命令一起执行,和传统mysql事务不同的是,Redis不支持回滚,在执行EXEC命令时,如果Redis事务中某条命令执行失败,其后的命令仍然会被执行,没有回滚。
- 隔离性:因为Redis是单线程处理任务,所以不会和其他的事务并发执行,天生具备隔离性。
- 持久性 :Redis的持久化(AOF,RDB)可以保证数据的持久性。
- 一致性:Redis不支持一致性,一致性是事务执行前后都有数据的一致,而Redis不支持回滚。
3.事务的错误处理
3.1简单说明
Redis在开启事务后会将接下来的命令先加入到队列当中,在事务提交时统一按顺序依次执行。所以,事务中命令出错就会在入队时和执行时。
3.2入队时产生的错误
语法错误,2.6.5之前会执行已经成功入队的命令,2.6.5及之后版本会自动丢弃整个事务。
6.2.5版本演示
3.3执行时产生的错误
命令与数据类型不匹配,redis会依次执行事务中正确的命令
4.Redis为什么不支持回滚操作
分析Redis事务出错情况可知,无论是入队期间的错误还是执行期间的错误,都是能在程序员编写代码时避免的错误,例如,如果查询将键增加 2 而不是 1,或者增加了错误的键,则回滚机制无法提供帮助。所以,Redis并没有支持回滚操作,并且不支持回滚功能,也使得Redis在事务上可以保持简洁和快速。
5.事务相关的一些命令
MULTI:开启事务
EXEC:提交事务,如果有监视键,执行EXEC后也会取消监视。
DESCARD:手动取消事务
WATCH:监控某个或某些键,用于为 Redis 事务提供检查和设置 (CAS) 行为。如果在执行 EXEC命令之前至少修改了一个监视键,则整个事务中止,并且EXEC返回Null 回复以通知事务失败。
UNWATCH:取消监视。
6.WATCH原理
watch是相当于乐观锁,为监视的键加上版本号。在开启事务时,就为监听的键加上版本号,如果事务中有监视键,在执行事务的时候会再次对比监视键的版本号,如果版本号不匹配则会取消整个事务,返回(nul)。
不知道你是否有这个疑问?
Redis是单线程处理执行命令的,怎么可能监视键的版本号会不同呢,也就是为什么会出现访问冲突呢?
没错,Redis是单线程处理,但是一旦开启事务,Redis的命令不是直接执行,而是先放到队列,在执行。也就是确认某个监视键的版本号是在开始事务时,在这个事务执行前,有可能其他的命令已经修改了这个监视键,从而版本号发生改变,这是当事务提交就不会执行这个事务了。
7.WATCH(监视)用法
- 监视k1
- 先开启上图的事务,在开启下图的事务
- 写好中间命令
- 先提交上图事务,在提交下图事务
分析:因为上下图同时监视k1,在上图未提交前下图开启了事务,此时两图对k1的版本号相同。
在上图提交事务后,k1的版本号就会加1,
之后提交下图事务,对比版本号发现不对,则取消整个事务。所以keys *中不会有k4、k5。