Redis乐观锁在电影购票业务中的应用

【辰兮要努力】:hello你好我是辰兮,很高兴你能来阅读,昵称是希望自己能不断精进,向着优秀程序员前行!

博客来源于项目以及编程中遇到的问题总结,偶尔会有读书分享,我会陆续更新Java前端、后台、数据库、项目案例等相关知识点总结,感谢你的阅读和关注,希望我的博客能帮助到更多的人,分享获取新知,大家一起进步!

吾等采石之人,应怀大教堂之心,愿你们奔赴在各自的热爱中…


一、Redis序言

Redis键值对设计:Redis在电影票系统的设计与实现

继续整理电影购票的项目中涉及到Redis事务和Redis的乐观锁的相关概念,现整理一下相关知识,来更加深入了解

在这里插入图片描述

在高并发的项目中,常常要用一些方法来保障数据的准确性,通过这种手段保证了当前用户和其他用户一起操作的时候,所得到的结果和他单独操作是一样的,这就是我们常说的并发控制。简单的说就是你不影响别人,别人操作也不影响你。

用电影购票业务解释,如果此时你购买了电影票但是你未支付,此时有一个十五分钟的支付时间,这个座位就是被占的,其他用户是无法购买你这个座位的。


如果购买成功了会怎么样?

在这里插入图片描述

那就会出现两张一样的票在同一个座位,这不算是交通事故嘛哈哈


二、Redis事务

回顾一下Redis事务?

1、Redis中的事务(transaction)是一组命令的集合。

2、事务同命令一样都是Redis最小的执行单位,一个事务中的命令要么都执行,要么都不执行。

3、Redis事务的实现需要用到 MULTI 和 EXEC 两个命令,事务开始的时候先向Redis服务器发送 MULTI 命令,然后依次发送需要在本次事务中处理的命令,最后再发送 EXEC 命令表示事务命令结束。

Redis的事务是下面4个命令来实现

Redis的事务是下面4个命令来实现 
1.multi,开启Redis的事务,置客户端为事务态。 
2.exec,提交事务,执行从multi到此命令前的命令队列,置客户端为非事务态。 
3.discard,取消事务,置客户端为非事务态。 
4.watch,监视键值对,作用时如果事务提交exec时发现监视的监视对发生变化,事务将被取消。 

三、Redis乐观锁

无论是悲观锁还是乐观锁,都是我们定义的一个概念

在这里插入图片描述

乐观锁:redis大多数是基于数据版本(version)的记录机制实现的。即为数据增加一个版本标识,在基于数据库表的版本解决方案中,一般是通过为数据库表添加一个version字段来实现。在读取数据时,将此版本号一同读出,之后更新时对此版本号加1。此时,将提交数据的版本号与数据库表对应记录的当前版本号进行对比,如果提交的数据版本号大于数据库当前版本号,则予以更新,否则认为是过期数据。

Redis中对乐观锁的实现: 假设有一个age的key,我们开启两个session来对age进行赋值操作。
session1:
127.0.0.1:6379> get age 
"10" 
127.0.0.1:6379> watch age #打开对age键的监控(监控其他操作是否对age键有修改操作) 
OK
127.0.0.1:6379> multi #开启事务上下文 
OK

session2: 
127.0.0.1:6379> set age 20 
OK
127.0.0.1:6379> get age 
"20"

再看session1: 
127.0.0.1:6379> set age 30 #在session2中操作age后,我们在session1中继续操作age
127.0.0.1:6379> exec #执行事务 返回nil 事务执行不成功。 
(nil) 
127.0.0.1:6379> get age 
"20"

在这里我们发现事务不能执行成功,这就是因为session1中的数据版本已经小于数据库中的数据版本。这就是Redis的乐观锁。

在这里插入图片描述


Redis的乐观锁设置

当我们点击购票后我们的redis的座位会被锁定,这样的好处,避免两个人购买相同的座位。每一次购票到完成就相当于一次Redis的事务,我们可以思考这次购票要么成功,要么失败,不然就会导致两个人购买同一张票的情况。具体的操作如下,即确保了不能重复购买电影票。用户在选座的时候执行multi这个方法。
在这里插入图片描述

其实简单的来说就是当我已经预定座位(未支付)此时我都会对这个座位进行相关的监听watch,其它的人无法再对我的座位进行购买预定等相关操作,直到我提交事务exec。

这样座位就不会卖给两个人了。


测试环节如何测试上述Redis乐观锁的成功?

你先购买几张电影票,到付款界面,不支付,然后退出去,再进来选座页面,你可以看到刚刚选座的座位边红色了,这是因为座位的显示也是从Redis中封装出来的,具体详情业务请参考我上一篇文章。


业务逻辑补充讲解

这里是我们点击购票后所进入的页面,我们可以对比上述的购票座位,检查发现是一致的,我们购票后通过redis锁定座位,和电影院的业务逻辑一样,我们设计了十五分钟的过期时间,即如果你十五分钟内未进行支付,则会出现订单支付失败,请重新购票。

这里前端和后台都要做定时器,Redis选座超过十五分钟要把这个座位释放掉,前端要提示用户在规定时间内完成支付。

这样的好处是为了防止恶意占座的情况。

在这里插入图片描述


悲观锁解释

悲观锁是基于一种悲观的态度类来防止一切数据冲突,它是以一种预防的姿态在修改数据之前把数据锁住,然后再对数据进行读写,在它释放锁之前任何人都不能对其数据进行操作,直到前面一个人把锁释放后下一个人数据加锁才可对数据进行加锁,然后才可以对数据进行操作,一般数据库本身锁的机制都是基于悲观锁的机制实现的;

在这里插入图片描述

乐观锁比较适用于读多写少的情况(多读场景),悲观锁比较适用于写多读少的情况(多写场景)。


The best investment is to invest in yourself.

在这里插入图片描述

2020.11.15 晚21:51 愿你们奔赴在自己的热爱里!

猜你喜欢

转载自blog.csdn.net/weixin_45393094/article/details/109710657