1.基本概念:
Redis单条命令是保证原子性的,但是Redis事务是不保证原子性。
Redis事务本质:一组命令的集合。一个事务中的所有命令都会被序列化,在事务执行过程中,会按照顺序执行。
即按照一次性、顺序性、排他性 执行一系列命令。
解释:把3个set命令放在一块执行,那么这3条命令入队,形成一个队列。队列中的命令执行过程中不允许被打断。(即要么全部成功,要么全部失败)
Redis事务没有隔离级别的概念。
所有的命令在事务中,并没有直接被执行(入队的时候未执行),只有发起执行命令的时候,才会执行。
Redis事务3个阶段:
- 开启事务(multi)
- 命令入队(这里写的命令都会入事务队列)
- 执行事务(exec)
正常执行事务流程
1 | multi # 开启命令 |
放弃事务
1 | multi |
2.关于事务执行中的错误
编译型异常:(导致编译器报错的异常)
命令或代码有问题,事务中所有的命令都不会执行。(要么都成功,要么都失败)
1 | multi |
运行时异常(如1/0,数组下标越界等)
如果事务队列中某条命令存在语法性错误,那么在执行的时候,其他命令是可以正常执行的。错误的那条命令会抛出异常。
所以说Redis事务是不保证原子性的。
1 | set k1 "aa" |
3.监控(watch)
悲观锁
- 很悲观,认为什么时候都会出问题,所以无论做什么都会加锁。
- 无论做什么都有加锁,解锁步骤,影响性能
乐观锁
- 很乐观,认为什么时候都不会出现问题,所以不会上锁。
- 只在更新数据的时候去判断一下,在此期间是否有人修改过数据。
- 在mysql中,用version字段去处理。(获取version,更新的时候比较version)
- 在Redis中,用watch字段去处理。
Redis 的监控测试
正常执行举例:
1 | set money 100 # 设置初始资金 100 |
事务执行失败的处理:
1 | unwatch # 如果发现事务执行失败,就先解锁 |