Redis学习(三)---事务、监视
Redis事务本质
- Redis事务的本质是一组命令的集合
- 事务支持一次性执行多个命令
- 一个事务中的所有概念都会被 序列化
- 在执行过程中,事务会顺序的执行命令,并且不让其他命令影响事务
- 总结:redis事务就是一次性、顺序性、排他性的执行一个队列中的一系列命令
特点
1、Redis没有事务隔离级别
- 批量操作在发送 EXEC 命令前被放入队列缓存,并不会被实际执行,也就不存在事务内的查询要看到事务里的更新,事务外查询不能看到。
2、Redis事务不保证原子性
- Redis中,单条命令是原子性执行的,但事务不保证原子性,且没有回滚。事务中任意命令执行失败,其余的命令仍会被执行。
Redis事务的三个阶段
- 开始事务(multi)
- 命令入队(queued)
- 执行事务(exec)
异常
1、编译时异常(命令行异常)
- 编译时异常一般是命令或者命令格式错误
- 这中错误在写进队列是就会报错
- 一旦错误,整个事务都将会失败
例:
2、运行时异常(语法性异常:1除以0)
- 这个异常能正常进入队列
- 在执行事务后才会抛出异常
- 事务的其他命令不受影响
例:decr只能使用在integer类型上
Redis事务的命令
- multi 开启事务
- exec 执行事务
- discard 撤销事务
- watch 【key】… 监视key。可以一次性监视多个
(当监视的key在事务中被修改但没有提交事务是,其线程对该key进行修改,会导致这整个事务失败,返回nil) - unwatch 放弃所有的监视
监视
通过监视可以实现乐观锁
- 乐观锁:对于数据冲突保持一种乐观态度,操作数据时不会对操作的数据进行加锁(这使得多个任务可以并行的对数据进行操作),只有到数据提交的时候才通过一种机制来验证数据是否存在冲突(一般实现方式是通过加版本号然后进行版本号的对比方式实现)
- 悲观锁:对于数据冲突保持一种悲观态度,它是以一种预防的姿态在修改数据之前把数据锁住,然后再对数据进行读写,在它释放锁之前任何人都不能对其数据进行操作,直到前面一个人把锁释放后下一个人数据加锁才可对数据进行加锁,然后才可以对数据进行操作,一般数据库本身锁的机制都是基于悲观锁的机制实现的
特点:
- 一般只有在事务中在会用到监视
- 当发生数据冲突时,该事物执行后会返回一个nil,并在这个事务中的所有命令都无效
- 每次监视,只能监视一个事务,当这个事务结束时,监视状态也结束
- 在监视的事务内解除监视(unwatch)是无效的,必须得在其他线程(事务外)解除监视