首页 > 其他分享 >5

5

时间:2024-06-11 22:55:13浏览次数:6  
标签: 事务 127.0 fund 0.1 6379 QUEUED

Redis事务

2023年3月15日00:06:36

一、redis的事务

redis事务特点

  • redis单条命令是原子性操作
  • redis事务本质是一组命令的集合
  • redis事务不保证原子性
  • 事务中所有的命令会被序列化,按照顺序执行
  • 一次性、顺序性、排他性
  • redis事务没有隔离级别

事务流程

  • 开启事务(multi)
  • 命令入队
  • 执行事务(exec)
  • 取消事务(discard)
#开启事务
127.0.0.1:6379[1]> multi
OK
#第一条命令
127.0.0.1:6379[1]> set name hyt
QUEUED
#第二条命令
127.0.0.1:6379[1]> set age 33
QUEUED
#第三条命令
127.0.0.1:6379[1]> get name
QUEUED
#第四条命令
127.0.0.1:6379[1]> del name
QUEUED
#执行事务,这时候才会将命令按照顺序执行
127.0.0.1:6379[1]> exec
1) OK
2) OK
3) "hyt"
4) (integer) 1
127.0.0.1:6379[1]> get name
(nil)
127.0.0.1:6379[1]> get age
"33"

事务异常

  • 编译型异常:命令错误,在事务执行的时候直接报错,所有命令都不会执行
  • 运行时异常:其他命令依然可以执行
#编译异常
127.0.0.1:6379[1]> multi
OK
127.0.0.1:6379[1]> set name hyt
QUEUED
#这条命令拼写错误
127.0.0.1:6379[1]> sett age 33
(error) ERR unknown command `sett`, with args beginning with: `age`, `33`,
127.0.0.1:6379[1]> get name
QUEUED
127.0.0.1:6379[1]> del name
QUEUED
#执行时候直接抛出异常,所有的命令都没有执行
127.0.0.1:6379[1]> exec
(error) EXECABORT Transaction discarded because of previous errors.
#运行时异常
127.0.0.1:6379[1]> multi
OK
#设置name = hyt
127.0.0.1:6379[1]> set name hyt
QUEUED
#设置自增,这里会异常因为name的值是字符串
127.0.0.1:6379[1]> decr name
QUEUED
127.0.0.1:6379[1]> set age 33
QUEUED
127.0.0.1:6379[1]> get name
QUEUED
127.0.0.1:6379[1]> get age
QUEUED
#执行事务发现第二条命令出现错误,但是后面的命令依然正常执行
127.0.0.1:6379[1]> exec
1) OK
2) (error) ERR value is not an integer or out of range
3) OK
4) "hyt"
5) "33"

二、redis监控

  • 悲观锁
    • 很悲观,认为什么时候都会出现问题,做任何操作都会加锁
  • 乐观锁
    • 很乐观,认为什么时候都不会出问题,所以不会上锁!更新数据的时候去判断一下,在此期间是否有人修改过这个数据
    • 获取version
    • 更新的时候比较version

watch实现乐观锁

  • watch在事务开启前启动监控
  • 如果在事务执行前发现监控的值发生变化,事务将执行失败
  • watch在事务执行之后,无论成功或者失败都会自动解除监控
  • unwatch解除监控
###################################打开客户端1
#我们使用第一个客户端设置key fund的值为1300
5) "1300"
#客户端1开启监控 watch key
127.0.0.1:6379[1]> watch fund
OK
#客户端1开启事务
127.0.0.1:6379[1]> multi
OK
#fund-900
127.0.0.1:6379[1]> decrby fund 900
QUEUED
#fund+250
127.0.0.1:6379[1]> incrby fund 250
QUEUED
#查询结果
127.0.0.1:6379[1]> get fund
QUEUED

###################################打开客户端2
#在第一个客户端执行事务之前,开启第二个客户端
127.0.0.1:6379[1]> get fund
"1300"
#客户端2修改fund的值
127.0.0.1:6379[1]> set fund 9000
OK

###################################回到客户端1
#客户端1执行事务,发现执行失败了,因为使用watch对fund的值进行了监控,然后开启了事务,但是在事务执行之前,fund被其他客户端进行了修改,监控发现fund变化之后,执行事务失败,实现乐观锁
127.0.0.1:6379[1]> exec
(nil)

标签:,事务,127.0,fund,0.1,6379,QUEUED
From: https://www.cnblogs.com/hyt810/p/18242959

相关文章