redis中的乐观锁和悲观锁

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了redis中的乐观锁和悲观锁相关的知识,希望对你有一定的参考价值。

参考技术A 乐观锁:这个世界是美好的,别人肯对不会在我操作数据前进行更改。在redis中,乐观锁指的是只是对key上锁,只要key不变就代表不会出问题。redis中的事务multi默认使用乐观锁,这将会导致一个问题:在秒杀这种高并发环境下,容易造成超卖问题。如,在一件商品只剩一件时,这时A用户开启事务只准备抢购,而就在A完成事务之前,B用户已经抢了这件商品,当A完成事务后,库存数量为-1。为了解决这个问题,可以引进悲观锁。

悲观锁:这个世界一切东西都是不可信的。在redis中,悲观锁指的是对数据key和都value都上锁,只要这个数据有一点小改动,事务将失败。因此上面的秒杀活动,在开启事务前,可对库存上锁:watch,只要在这个watch之后,别的进程或线程对这个库存有修改,本线程的事务将不会执行成功。

redis08_redis的事务 multi(声明一个事务)exec(执行一个事务)redis里面为什么要有事务悲观锁和乐观锁(可以并发提高吞吐量)

redis的事务系列文章目录

前言

redis的事务是什么,它跟mysql的事务是一样的吗?
实际上redis的事务和mysql的事务是不一样的,我们不能把他们混为一谈,应该分开来理解

第一种情况:组队成功 exec





第二种情况:组队不成功,队伍解散


multi在组队的过程中只要有一条语句报错了,队伍就会解散,队伍解散之后,所有队列都作废了
解散以后,你再怎么执行exec都不会成功了

第三种情况:编译时不报错就执行,与MySQL不同,不回滚


组队的时候没有发现语法错误的话,执行的时候我就不管,直接给你执行了
那么这是不是说明redis中没有回滚这个功能呢?
可以百度看一下

redis里面为什么要有事务


悲观锁和乐观锁


悲观锁不允许并发执行,而乐观锁是可以并发执行的
乐观锁即我始终认为你这个账户不会有人去操作,每个人都可以去拿
如下图,假设你有10000块,你的前女友双十一买东西,发过来一个请求,需要8000,前前女友要买包包需要2000
这个时候他们俩谁先抢到,就看谁的手速了,那么假设前女友快一些,扣掉了8000剩余2000,那么此时你的账户就会默认逻辑上加了一个版本号 v1.1
这个时候前前女友的请求就会去对比版本号,v1.0 对不上v1.1,这个时候,她的操作就会失败,以此类推,不断的加版本号,这就叫乐观锁

过年过节买火车票就是这样的一个场景
我们买火车票的时候比如8点放票,这个时候大家都能看到票,只是看谁手速快,看谁先下订单
所以有时候8点踩点来抢票的人很难抢到票,而后面来的人反而比较容易抢到票,因为最先来的人版本号是V1.0,已经不通过了,所以如果抢票来早了,又没有抢到票,那么就重新进一下,更新一下版本号,很大可能会更容易抢到票

悲观锁和乐观锁的使用

关系型数据库基本上都是悲观锁,比如mysql和oracle,非关系型数据库redis是乐观锁

在redis中怎么体现乐观锁


如下图:假定有2个进程,如果没有锁,拿到的数据会是多少

如果没有锁机制,拿到的数据可能会是1100 也可能会是1200,也可能是1300
所以我们需要事务,让他们一块执行
上图中第二个进程,也可以进行数据增长


代码演示锁


注意上锁/监听 watch 要结合 事务 multi 来使用



不管开多少个进程,在执行之前,大家都一样,但是执行之后,只有一个能够成功,因为成功那个更改了乐观锁的版本号,导致其它的匹配不了最新的版本号,所以其它的会执行失败
而最终只有一个能够成功

以上是关于redis中的乐观锁和悲观锁的主要内容,如果未能解决你的问题,请参考以下文章

redis乐观锁和悲观锁在spring boot的使用

redis乐观锁和悲观锁在spring boot的使用

大数据之Redis:悲观锁和乐观锁

mysql中的乐观锁和悲观锁

mysql中的锁机制之悲观锁和乐观锁

乐观锁和悲观锁