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

本文涉及的产品
云原生内存数据库 Tair,内存型 2GB
云数据库 Redis 版,标准版 2GB
推荐场景:
搭建游戏排行榜
简介: 分享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.

在这里插入图片描述

愿你们奔赴在自己的热爱里!

相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore     ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库 ECS 实例和一台目标数据库 RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
目录
相关文章
|
22天前
|
缓存 NoSQL Java
Redis深度解析:解锁高性能缓存的终极武器,让你的应用飞起来
【8月更文挑战第29天】本文从基本概念入手,通过实战示例、原理解析和高级使用技巧,全面讲解Redis这一高性能键值对数据库。Redis基于内存存储,支持多种数据结构,如字符串、列表和哈希表等,常用于数据库、缓存及消息队列。文中详细介绍了如何在Spring Boot项目中集成Redis,并展示了其工作原理、缓存实现方法及高级特性,如事务、发布/订阅、Lua脚本和集群等,帮助读者从入门到精通Redis,大幅提升应用性能与可扩展性。
49 0
|
26天前
|
Kubernetes NoSQL Redis
【Azure Redis】部署在AKS中的应用连接Redis时候出现Unable to connect to Redis server
【Azure Redis】部署在AKS中的应用连接Redis时候出现Unable to connect to Redis server
【Azure Redis】部署在AKS中的应用连接Redis时候出现Unable to connect to Redis server
|
1月前
|
NoSQL Java Redis
Spring Boot集成Redis全攻略:高效数据存取,打造性能飞跃的Java微服务应用!
【8月更文挑战第3天】Spring Boot是备受欢迎的微服务框架,以其快速开发与轻量特性著称。结合高性能键值数据库Redis,可显著增强应用性能。集成步骤包括:添加`spring-boot-starter-data-redis`依赖,配置Redis服务器参数,注入`RedisTemplate`或`StringRedisTemplate`进行数据操作。这种集成方案适用于缓存、高并发等场景,有效提升数据处理效率。
254 2
|
26天前
|
缓存 NoSQL Linux
【Azure Redis 缓存】应用中出现连接Redis服务错误(production.ERROR: Connection refused)的排查步骤
【Azure Redis 缓存】应用中出现连接Redis服务错误(production.ERROR: Connection refused)的排查步骤
|
27天前
|
NoSQL 网络协议 Shell
【Azure 应用服务】App Service 项目部署成功后,应用连接 Azure Redis时报错 Could not get a resource from the pool
【Azure 应用服务】App Service 项目部署成功后,应用连接 Azure Redis时报错 Could not get a resource from the pool
|
28天前
|
缓存 NoSQL 网络安全
【Azure Redis 缓存 Azure Cache For Redis】Azure Redis由低级别(C)升级到高级别(P)的步骤和注意事项, 及对用户现有应用的潜在影响,是否需要停机时间窗口,以及这个时间窗口需要多少的预估问题
【Azure Redis 缓存 Azure Cache For Redis】Azure Redis由低级别(C)升级到高级别(P)的步骤和注意事项, 及对用户现有应用的潜在影响,是否需要停机时间窗口,以及这个时间窗口需要多少的预估问题
|
2月前
|
运维 NoSQL Serverless
Serverless 应用引擎使用问题之首次启动无法获取redis连接,重启实例后可以获取,是什么原因
阿里云Serverless 应用引擎(SAE)提供了完整的微服务应用生命周期管理能力,包括应用部署、服务治理、开发运维、资源管理等功能,并通过扩展功能支持多环境管理、API Gateway、事件驱动等高级应用场景,帮助企业快速构建、部署、运维和扩展微服务架构,实现Serverless化的应用部署与运维模式。以下是对SAE产品使用合集的概述,包括应用管理、服务治理、开发运维、资源管理等方面。
Serverless 应用引擎使用问题之首次启动无法获取redis连接,重启实例后可以获取,是什么原因
|
2月前
|
NoSQL Redis
Redis set数据类型命令使用及应用场景使用总结
Redis set数据类型命令使用及应用场景使用总结
32 1
|
2月前
|
存储 NoSQL 容灾
Redis问题之压缩列表zipList在Redis中有哪些应用场景
Redis问题之压缩列表zipList在Redis中有哪些应用场景
|
3月前
|
NoSQL Redis
Redis系列学习文章分享---第五篇(Redis实战篇--优惠券秒杀,全局唯一id 添加优惠券 实现秒杀下单 库存超卖问题分析 乐观锁解决超卖 实现一人一单功能 集群下的线程并发安全问题)
Redis系列学习文章分享---第五篇(Redis实战篇--优惠券秒杀,全局唯一id 添加优惠券 实现秒杀下单 库存超卖问题分析 乐观锁解决超卖 实现一人一单功能 集群下的线程并发安全问题)
89 0