Redis之事务与锁

基本概念

  • Redis的事务本质是一组命令的集合,一个事务中所有的命令都会被序列化,按照顺序执行
  • Redis的单条语句保持原子性,但是事务不保持原子性
  • Redis的事务没有隔离级别的概念
  • 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> get k1
QUEUED
127.0.0.1:6379> set k3 v3
QUEUED
127.0.0.1:6379> get k2
QUEUED
127.0.0.1:6379> exec       #执行事务
1) OK
2) OK
3) "v1"
4) OK
5) "v2"
127.0.0.1:6379>

放弃事务(discard)

127.0.0.1:6379> flushdb
OK
127.0.0.1:6379> multi
OK
127.0.0.1:6379> set k1 v1
QUEUED
127.0.0.1:6379> discard     #放弃事务
OK
127.0.0.1:6379> get k1      #队列中的命令都不会执行
(nil)

事务执行中的错误

  • 编译型错误,即代码本身写的有问题,那么队列中所有命令的执行都不会成功
127.0.0.1:6379> multi
OK
127.0.0.1:6379> set k1 v1
QUEUED
127.0.0.1:6379> setget 666
(error) ERR unknown command `setget`, with args beginning with: `666`,
127.0.0.1:6379> set k2 v2
QUEUED
127.0.0.1:6379> exec
(error) EXECABORT Transaction discarded because of previous errors.
127.0.0.1:6379> get k1
(nil)
127.0.0.1:6379> get k2
(nil)
  • 运行时异常,例如写了1/0这样的代码,其本身语法没有错误,那么其他语句可以正常执行
127.0.0.1:6379> multi
OK
127.0.0.1:6379> set k1 v1
QUEUED
127.0.0.1:6379> incr k1     #语句本身没问题,但是key并不能自增
QUEUED
127.0.0.1:6379> set k2 v2
QUEUED
127.0.0.1:6379> get k1
QUEUED
127.0.0.1:6379> get k2
QUEUED
127.0.0.1:6379> exec        #其他语句正常执行
1) OK
2) (error) ERR value is not an integer or out of range
3) OK
4) "v1"
5) "v2"

锁的分类

  • 悲观锁:悲观的认为什么时候都会出问题,无论做什么都会加锁
  • 乐观锁:乐观的认为什么时候都不会出问题,只会在更新数据的时候去判断该数据是否被改动过,例如MySQL中的version字段

Redis中的乐观锁,监控 watch

  • 单线程操作,不监视的情况下,对数据进行改动
127.0.0.1:6379> set money 1000     
QUEUED
127.0.0.1:6379> set out 0
QUEUED
127.0.0.1:6379> decrby money 200       #余额减少200
QUEUED
127.0.0.1:6379> incrby out 200         #话费增加200
QUEUED
127.0.0.1:6379> exec
1) OK
2) OK
3) (integer) 800 
4) (integer) 200
  • 多线程的情况下,如果进行了监视,而期间另一个线程对数据进行了改动

    线程一,在exec前执行线程2

127.0.0.1:6379> watch money                   #监控money
OK 
127.0.0.1:6379> multi
OK
127.0.0.1:6379> decrby money 200
QUEUED
127.0.0.1:6379> incrby out 200
QUEUED
127.0.0.1:6379> exec                          #提交事务失败
(error) EXECABORT Transaction discarded because of previous errors.

线程二

127.0.0.1:6379> set money 2000
OK

查看现在的money为2000,代表事务提交失败

127.0.0.1:6379> get money
"2000"
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值