1、事务是什么?
事务本质是一组命令的集合,它可以一次执行多个命令。一个事务中的所有命令都会序列化,按顺序、串行地去执行,且不允许加塞其它的命令,不会被其它命令插入。
2、事务能干嘛?
把多个命令放到一个队列中,并能一次性、按顺序、排他性地去执行这些命令
3、redis事务怎么玩?
1.常用命令
redis常用命令2.正常执行
1.使用multi
启动事务
2.执行想要在事务中进行的命令(正确可执行的命令)
3.使用exec
执行事务
结果:本次事务正常执行
3.放弃事务
1.使用multi
启动事务
2.执行想要在事务中进行的命令(正确可执行的命令)
3.使用discard
取消本次事务
结果:本次事务取消,无法执行
4.全部失败
1.使用multi
启动事务
2.执行想要在事务中进行的命令(注意:其中有错误的命令)
3.使用exec
执行事务
结果:本次事务中的命令,全部执行失败
5.冤头债主
1.使用multi
启动事务
2.执行想要在事务中进行的命令(注意:其中没有错误命令,但其中有命令无法对目标对象执行操作)
3.使用exec
执行事务
结果:本次事务中的命令,除了错误那条,其它都正常执行
4、watch监控
- Watch指令类似乐观锁,在事务提交时,如果监控的Key的值已被别的客户端改变,比如某个list已被别的客户端push/pop过了,整个事务队列都不会被执行
- 通过WATCH命令在事务执行之前监控了多个Keys,倘若在WATCH之后有任何Key的值发生了变化,EXEC命令执行的事务都将被放弃,同时返回
Nullmulti-bulk
响应,用以通知调用者事务执行失败
1.悲观锁(Pessimistic Lock)
顾名思义,就是很悲观。每次去拿数据的时候都认这个数据会被别人进行修改了。所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会阻塞,直到它拿到锁,才能继续执行。
传统的关系型数据库里边就用到了很多这种锁机制,比如行锁,表锁等,读锁,写锁等,都是在做操作之前先上锁。性能影响较大。
2.乐观锁(Optimistic Lock),
顾名思义,就是很乐观。每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个数,可以使用版本号等机制。乐观锁适用于多读的应用类型,这样可以提高吞吐量。
乐观锁策略:提交版本必须大于记录当前版本才能执行更新
3.CAS(Check And Set)
WATCH 命令,类似乐观锁,可以为 Redis 事务提供 CAS(Check And Set)行为。
4.示例准备步骤_初始化信用卡可用余额和欠额
-
用事务设置信用卡可用余额和欠额
余额和欠款
5.示例1_无加塞篡改,先监控再开启multi,保证两笔金额变动在同一个事务内
- 监听余额
- 开启事务
- 模拟刷卡:增加欠额,扣除余额
-
启动事务
6.示例2_加塞篡改
watch
监控了key,如果key被修改了,后面一个事务的执行失效
- 监听余额
- 事务开始前,模拟转账:增加余额
- 开启事务
- 模拟刷卡:增加欠额,扣除余额
- 提交事务
-
查询余额和欠额
结果:事务中的模拟刷卡不执行,值是事务开始前的模拟转账操作后的结果.
7.示例3_监控的key被修改过,unwatch
释放本次监听,然后重新监听
在被监听的key修改后,unwatch
释放了监听,后面的事务能正常执行
- 监听余额
- 事务开始前,模拟存款:设置余额300
- 放弃监听
unwatch
- 重新监听
- 启动事务
- 事务后,模拟转账:增加余额200
-
提交事务
结果:由于放弃了事务开始前的监听,所以事务里的命令正常执行,余额的值=事务前存款后的余额300+事务中转账的额度200
image.png
5、excel
和watch
的关系
一旦执行了exec,事务之前加的watch监控锁都会被取消掉
6、redis事务的三个阶段
-
开启
MULTI
开始一个事务;(在此之前可以对想要监听的key进行watch
监听或unwatch
放弃监听) -
入队
将多个命令入队到事务中,接到这些命令并不会立即执行,而是放到等待执行的事务队列里面 -
执行
EXEC
命令触发事务(事务之前加的watch监控锁都会被取消掉)
6、redis事务的三个特性
- 单独的隔离操作
事务中的所有命令都会序列化、按顺序地执行。事务在执行的过程中,不会被其他客户端发送来的命令请求所打断。 - 没有隔离级别的概念
队列中的命令没有提交之前都不会实际的被执行,因为事务提交前任何指令都不会被实际执行,也就不存在”事务内的查询要看到事务里的更新,在事务外查询不能看到”这个让人万分头痛的问题。 - 不保证原子性
redis同一个事务中如果有一条命令执行失败,其后的命令仍然会被执行,没有回滚
网友评论