redis实现乐观锁

redis实现乐观锁,第1张

redis实现乐观锁

我们先介绍一下悲观锁和乐观锁:我们要知道我们java程序去做的时候是一定会去加锁的,比如说我们多条线程在并发执行的时候,一定会去加锁的

悲观锁:顾名思义,很悲观,就是认为什么时候都会出问题,无论干什么都加锁!所以说这种 *** 作是非常影响性能的,比如说sychronized默认就是这样,无论干什么都会去加锁,用完之后再去解锁!

乐观锁:顾名思义,很乐观,认为什么时候都不会出现问题,所以不会加锁!那不上锁,总得有个机制去处理并发这个问题,那这个时候,就会在更新数据的时候去判断一下,在此期间,是否有人去改动过这个数据。

我们在开发中,一般都是使用乐观锁的,很少使用悲观锁的,因为无论干什么都要去上锁,这个效率极其低下,乐观锁相对来说性能就会好很多,

那么在redis中实现乐观锁是用一个watch,就是去加一个监视器:

首先我们设置一个100块钱,然后设置一个出去的钱,比如说0元,这个时候我们加一个watch,监视我们的money,然后我们正常执行事务,我们在入队命令里去花掉20块钱,那么我们的out里是不是要加20块钱,我们执行这个事务,正常执行事务的话,余额就是80块,支出就是20块,说明现在这个乐观锁确实没有任何问题,那么它就可以执行成功,

那我们来演示下不正常的情况:

 假设我们执行第一个线程的时候,来了第二个线程,然后它把这个数据改变了,那会是怎样的 *** 作?

首先我们这里再启一个redis的客户端,我们还要知道当我们的事务正常执行成功之后,我们的这个watch监视就会自动取消掉

我们先在第一个客户端来监视这个money:

 

然后再开启事务,让我们这个money减去10块,out加10块钱,到这里我们并不直接去执行事务,

 

 这时另外一条线程突然插进来了,即我们第一个线程还没有去执行这个事务,我们第二条线程就进来把这个钱设置成1000了,即修改了数据

 

 

 这个money值变动了之后,这个watch就会告诉这个事务,这个money值被变动了,你当前的事务一定会提交失败,

我们再回到第一个线程,去执行下事务,看下效果,可以看到返回一个null,这就说明修改失败克了, 

 

所以得到的结论就是:watch命令 ,可以当做redis的乐观锁 *** 作!

它这个底层原理就是当我们使用watch命令之后,它就会获取这个key的值,然后监视,当我们去执行事务的时候,就会去更新这个值,更新的时候,首先它会去比较现在要更新的这个key值是否和之前获取到的值是一样的,如果一样,则没有任何问题,如果不一样,则代表有问题,执行事务时会失败!

那现在执行事务失败了怎么去解决呢?

 

首先如果我们发现事务执行失败,就先去解锁,然后再重新加锁,再次监视,这就好比我们放弃了之前的那个100块钱的值,现在监视的是被修改后的值,也就是1000块,然后继续执行事务就可以了 ,是不是跟自旋锁是一样的原理

以上就是redis执行乐观锁的 *** 作!

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/zaji/5692831.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-17
下一篇 2022-12-17

发表评论

登录后才能评论

评论列表(0条)

保存