了解Redis事务及Redis实现乐观锁

Redis事务

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

Redis没有隔离级别的概念
Redis单条命令保证原子性,但事务不保证原子性。
所有的命令在事务中并没有直接被执行,而是发起执行命令后才会执行。

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> exec   #执行事务
1) OK
2) OK
3) "v1"
4) OK

注意:
当事务执行完成后说明事务已经执行完毕,需要再次进行事务操作需要重新去开启事务。

放弃事务 :discard

127.0.0.1:6379> multi
OK
127.0.0.1:6379> set k1 v1 k2 v2
QUEUED
127.0.0.1:6379> set k4 v4
QUEUED
127.0.0.1:6379> DISCARD   #放弃事务
OK
127.0.0.1:6379> get k4  #获取不到值,因为事务被放弃,事务队列中的命令都不会被执行
(nil)

异常分析:

编译型异常:
代码有问题,命令写错。事务中所有的命令都不会被执行

运行时异常:
事务队列中存在着语法,当执行命令时存在的错误,正确的命令会正常执行,错误的命令会抛出异常。


监控 — Watch监视器

了解悲观锁和乐观锁

悲观锁:

  • 无论做什么都要加锁,认为任何情况都会出问题

乐观锁:

  • 认为什么时候都不会出问题,不会去上锁。
  • 获取version
  • 更新的时候比较version

我们通常使用乐观锁,因为悲观锁效率低下,无论什么时候都要去加锁。

测试:
正常执行状态下
单线程

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   #监视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
1) (integer) 90
2) (integer) 10

在多线程的情况下修改值,使用watch作为Redis的乐观锁操作。

127.0.0.1:6379> watch money   #监视money
OK
127.0.0.1:6379> multi
OK
127.0.0.1:6379> DECRBY money 20
QUEUED
127.0.0.1:6379> incrby money 20
QUEUED
127.0.0.1:6379> exec   #在执行之前另外一个线程修改了money对象值导致了事务执行失败。
(nil)

在另一个线程下修改money对象的值

127.0.0.1:6379> get money
"90"
127.0.0.1:6379> set money 1000
OK

解决:
如果修改失败,获取到最新的值即可。 先进行解锁操作,然后再次进行监视。

在这里插入图片描述
对比监视的值是否发生了变化,如果值没有发生变化,那么可执行成功。如果值在另外的线程中发生了变化就不能执行成功。 要想解决就要再次解锁,然后再次监视。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值