事务
事务
Redis单条命令是保证原子性的。但redis的事务是不保证原子性的
Redis事务本质:一组命令的集合!一个事务中的所有命令都会被序列化,在事务执行过程中,会按照顺序执行!
一次性,顺序性,排他性!执行一系列的命令
Redis事务没有隔离级别的概念 。
所有的命令在五中,并没有执行!只有发起执行命令的时候才会执行 Exec
---队列set set set 执行---
redis事务:
- 开启事务 multi
- 命令入队 reid命令
- 执行事务 exec
multi # 开启事务
# 入队
set k1 v1; #queued
set k2 v2; #queued
get k2; #queued
set k3 v3; #queued
#执行事务
exec #输出上面4条命令的返回结果
#放弃事务
discard
- 编译型异常:代码有问题,命令有错。事务中的所有命令都不会执行!exec执行事务时也是报错的
- 运行时异常:如果事务队列中,有一个命令操作错误,比如:一个字符串+1,exec时,这条命令报错。其他会正常执行
乐观锁,悲观锁
-
悲观锁:认为什么时候都会出问题,无论做什么都加锁
-
乐观锁:认为什么时候都不会出问题,无论做什么都不加锁,更新数据时去判断一下,在此期间有没有人修改过这个数据
- 获取version
- 更新时较verson,以version为条件
redis监视测试
watch加锁
单线程下:
set money 100
set out 0
wahtch money #监视money对象
multi #事务正常结束,数据期间没有发生变动,这个时候就正常执行
decrby moneny 20
incrby out 20
exec #80 20
多线程下:多线程修改值,使用watch可以单做redis的乐观锁
线程1:
先执行:
set money 100
set out 0
wahtch money #监视money对象,相当于get version
multi
decrby moneny 20
incrby out 20
exec #执行之前,另外一个线程修改了money值,事务就会执行失败
再执行线程2, 修改money值:
set money 200
unwatch解锁
如果发现事务执行失败,就先解锁。然后再获取锁unwath(获取最新的值),再去执行事务
unwatch #如果发现事务执行失败,就先解锁
watch money #获取最新的值,相当于select version
multi
decrby money 10
incryby money 10
exec #对比监视的值是否发生了变化,如果无变化就执行成功,如果变化了就执行失败,那就需再unwatch watch

浙公网安备 33010602011771号