Redis学习笔记(四)

事务

Redis事物本质:一组命令的集合。一个事务中的所有命令都会被序列化,在事务执行过程中,会按照顺序执行Exec

一次性、顺序性、排他性

----------队列 set set set 执行-----------           单线程

Redis事务没有隔离级别的概念

所有的命令在事务中,并没有直接被执行,只有发起执行命令的时候才会被执行。Exec

Redis单条保证原子性,但是事务不保证原子性!

事务:

  • 开启事务(multi)
  • 命令入队(…)
  • 执行事务(exec)

正常执行事务 一次事务执行完就结束了,要重新开启事务

127.0.0.1:6379> multi           #开启事务
OK
127.0.0.1:6379> set k1 v1      #命令入队
QUEUED
127.0.0.1:6379> set k2 v2
QUEUED
127.0.0.1:6379> set k3 v3
QUEUED
127.0.0.1:6379> get k2
QUEUED
127.0.0.1:6379> get k3
QUEUED
127.0.0.1:6379> exec          #执行事务
1) OK
2) OK
3) OK
4) "v2"
5) "v3"

放弃事务

127.0.0.1:6379> multi
OK
127.0.0.1:6379> set k1 v1
QUEUED
127.0.0.1:6379> set k2 v2
QUEUED
127.0.0.1:6379> set k3 v3
QUEUED
127.0.0.1:6379> DISCARD              #放弃事务
OK
127.0.0.1:6379> get k3
(nil)
127.0.0.1:6379> exec
(error) ERR EXEC without MULTI

编译型异常(代码有问题,命令有错),事务中所有命令都不会执行

127.0.0.1:6379> multi
OK
127.0.0.1:6379> set k1 v1
QUEUED
127.0.0.1:6379> set k2 v2
QUEUED
127.0.0.1:6379> getste k1
(error) ERR unknown command `getste`, with args beginning with: `k1`,
127.0.0.1:6379> set k3 v3
QUEUED
127.0.0.1:6379> exec
(error) EXECABORT Transaction discarded because of previous errors.

运行时异常(1/0)如果事务队列中存在语法问题,执行命令的时候,其他命令可以正常执行,错误的抛出异常。

127.0.0.1:6379> set k1 'v1'
OK
127.0.0.1:6379> multi
OK
127.0.0.1:6379> set k2 v2
QUEUED
127.0.0.1:6379> set k3 v3
QUEUED
127.0.0.1:6379> incr k1           #字符串不能自增一
QUEUED
127.0.0.1:6379> get k3
QUEUED
127.0.0.1:6379> exec
1) OK
2) OK
3) (error) ERR value is not an integer or out of range
4) "v3"

监控 锁

悲观锁:认为什么时候都会出问题,无论做什么都加锁

乐观锁:认为什么时候都不会出问题,更新数据的时候去判断字段

redis监视测试 乐观锁

#正常执行
127.0.0.1:6379> set money 100              #余额
OK  
127.0.0.1:6379> set out 0                 #花掉了多少钱
OK
127.0.0.1:6379> watch money               #watch监视
OK
127.0.0.1:6379> multi
OK
127.0.0.1:6379> DECRBY money 10
QUEUED
127.0.0.1:6379> INCRBY out 10
QUEUED
127.0.0.1:6379> exec
1) (integer) 90
2) (integer) 10

测试多线程执行

#客户端1
127.0.0.1:6379> set money 100
OK
127.0.0.1:6379> set out 0
OK
127.0.0.1:6379> watch money
OK
127.0.0.1:6379> multi
OK
127.0.0.1:6379> DECRBY money 10
QUEUED
127.0.0.1:6379> INCRBY out 10
QUEUED
127.0.0.1:6379> exec
(nil)
#客户端2
127.0.0.1:6379> get money
"100"
127.0.0.1:6379> set money 1000
OK

怎么解决

127.0.0.1:6379> unwatch           #1.如果发现事务执行失败,先解锁
OK
127.0.0.1:6379> watch money       #2.再加锁,获取最新的值
OK
127.0.0.1:6379> multi
OK
127.0.0.1:6379> DECRBY money 10
QUEUED
127.0.0.1:6379> INCRBY out 10
QUEUED
127.0.0.1:6379> exec       #3.比对监视的值是否发生了变化,如果发生了变化,那么可以执行成功,否则执行失败
1) (integer) 990
2) (integer) 10
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值