redis事务
数据库事务
所有的数据库操作都必须一次性完成,要么成功,要么失败。
redis事务
可以一次执行多个命令,本质上是一组命令的集合。一个事务中的所有命令都会序列化,按顺序地串行化执行而不被其他命令插入,不许加载(不许被不属于该集合的命令插入)。
- 开启:以MULTI开始一个事务
- 入队:将多个命令放到事务队列中,但不会立刻执行
- 执行:由EXEC命令触发事务
能干嘛
一个队列中,一次性、顺序性、排他性的执行一系列命令。
用法
常用命令
- DISCARD: 取消事务,放弃执行事务内的所有命令
- EXEC: 执行所有事务块内的命令
- MULTI: 标记一个事务块的开始
- UNWATCH: 取消WATCH对所有key的监控
- WATCH key: 监控一个或多个key, 如果在事务执行之前这个key已被其他命令所改动,那么事务将会被打断
正常执行
- MULTI
- EXEC
放弃事务
- MULTI
- DISCARD
全体连坐(类似于编译错误(语法错误))
在一个命令组中,如果其中的某条命令出现差错,则所有命令都无法成功执行,在最终提交时也是失败的。
冤头债主(类似于运行错误(运行错误))
在一个命令组中,如果其中的某条命令出现差错,则对的命令继续执行,错的命令无法执行。
在redis中,不提供事务回滚的功能,因此开发者必须在事务执行出错后,自行恢复数据库状态。
watch监控
redis使用watch来提供乐观锁定,类似于CAS(Check-And-Set)。
- 悲观锁:顾名思义,也就是很悲哀,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会阻塞block,直到它拿到锁。
- 乐观锁:顾名思义,也就是很乐观,每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会判断在此期间别人有没有去更新这个数据。乐观锁策略:提交版本必须大于当前版本才能执行更新。类似git提交。
- CAS:redis支持使用CAS的乐观锁。
对于watch,初始化key和balance两个key,先监控在开启multi,保证两key变动在同一个事务内。
如果有加塞篡改,redis在修改的时候会检测数据是否被修改,如果被更改过,则执行失败。
- 一旦执行了exec操作之前加的监控都会被取消掉了
- 当客户端连接丢失的时候(比如退出链接),所有东西都会被取消监视。