Redis驱动的图书秒杀:商品购买及取消操作全指南

引言

在当前互联网应用程序的开发进程中,高并发场景下的系统性能优化始终是开发者要应对的重要课题。特别是在像电商、零售这类涉及大量商品库存管理的场景中,怎样高效处理用户的购买请求、确保库存数据的一致性以及系统的响应速度,成了系统设计的关键所在。此项目基于Spring Boot框架,结合Redis缓存技术,构建了一个图书购买与库存管理系统,着重解决高并发环境下库存扣减、购买操作等核心业务场景。

Redis作为高性能的内存数据库,具备读写速度快、支持丰富数据结构、支持事务和持久化等特性,特别适合用于缓存热点数据、处理高并发的库存扣减等场景。本系统把图书库存数据存储在Redis中,借助其高速读写能力来处理用户的购买和取消购买操作,同时通过数据库持久化存储用户的购买记录,实现了缓存与数据库的双重数据保障。

本文将会详细介绍该系统的设计与实现,涵盖前后端交互接口、整体代码逻辑、Redis配置、后端各层代码讲解以及前端页面实现,最后对整个系统进行总结与优化思考。
在这里插入图片描述

1. 前后端交互接口

1.1 接口设计概述

该系统达成了图书购置、批量购置、取消购置、批量取消购置以及分页查询等关键功能,前后端通过RESTful API开展交互。接口设计遵循简洁、清晰的原则,以保证前端页面能够高效地与后端服务进行数据交换。

1.2 核心接口详情

1.2.1 购买图书接口
  • 接口URL/specialNormal/buy
  • 请求方法 :POST
  • 请求参数
    • bookId:整数类型,要购买的图书ID
  • 请求头 :需包含用户会话信息(通过HttpSession获取用户信息)
  • 响应结果
    • 成功:{"status":"SUCCESS"}
    • 失败:{"status":"FAIL"}
  • 接口功能 :处理单个图书的购买请求,包含库存检查、库存扣减、更新用户购买记录等逻辑
1.2.2 批量购买图书接口
  • 接口URL/specialNormal/batchPurchaseSpecialBook
  • 请求方法 :POST
  • 请求参数
    • idList:整数列表,要购买的图书ID列表
  • 请求头 :需包含用户会话信息
  • 响应结果
    • 成功:{"status":"SUCCESS"}
    • 失败:{"status":"FAIL"}
  • 接口功能 :处理多个图书的批量购买请求,通过循环调用单个购买接口来实现
1.2.3 取消购买图书接口
  • 接口URL/specialNormal/noBuy
  • 请求方法 :POST
  • 请求参数
    • bookId:整数类型,要取消购买的图书ID
  • 请求头 :需包含用户会话信息
  • 响应结果
    • 成功:{"status":"SUCCESS"}
    • 失败:{"status":"FAIL"}
  • 接口功能 :处理单个图书的取消购买请求,包含恢复库存、更新用户购买记录等逻辑
1.2.4 批量取消购买图书接口
  • 接口URL/specialNormal/batchNoBuyBook
  • 请求方法 :POST
  • 请求参数
    • idList:整数列表,要取消购买的图书ID列表
  • 请求头 :需包含用户会话信息
  • 响应结果
    • 成功:{"status":"SUCCESS"}
    • 失败:{"status":"FAIL"}
  • 接口功能 :处理多个图书的批量取消购买请求,通过循环调用单个取消购买接口来实现
1.2.5 分页查询特价购物车接口
  • 接口URL/specialNormal/getSpecialBookListOfNormalByPage
  • 请求方法 :GET
  • 请求参数
    • currentPage:整数类型,当前页码
    • pageSize:整数类型,每页显示数量
  • 请求头 :需包含用户会话信息
  • 响应结果
    • 成功:{"status":"SUCCESS","data":{"total":总记录数,"bookInfoList":图书列表,"pageRequest":分页参数}}
    • 失败:{"status":"FAIL","errorMessage":"错误信息"}
  • 接口功能 :依据分页参数查询用户特价购物车中的图书列表,支持分页展示

1.3 接口设计特点

  1. 无状态设计 :接口设计遵循RESTful原则,尽量保持无状态,通过会话(HttpSession)获取用户信息
  2. 参数校验 :每个接口都进行了基本的参数校验,以确保输入数据的合法性
  3. 统一响应格式 :使用统一的Result类作为响应结构,包含状态码、错误信息和数据内容
  4. 批量操作支持 :提供批量购买和批量取消购买接口,提升用户操作效率
  5. 分页查询 :实现分页查询接口,优化大数据量下的前端展示性能

这些接口设计不仅满足了基本的业务需求,还考虑了系统的可扩展性和性能优化,为后续功能迭代奠定了良好的基础。

2. 整体的代码逻辑

2.1 系统初始化流程

系统启动之时,会自动启动数据初始化流程,将数据库中的图书数据同步到Redis缓存中,具体流程如下:

  1. InitializingBean触发DataInitService实现了InitializingBean接口,在容器初始化完成后,afterPropertiesSet()方法会被自动调用
  2. 数据同步服务调用 :在afterPropertiesSet()方法中,调用DataSyncServicesyncMysqlToRedis()方法
  3. 数据库查询DataSyncService通过RedisMapper从数据库查询图书信息
  4. Redis批量存储 :将查询到的图书信息批量存入Redis,使用bookInfoId:{id}的格式作为Key,Value使用JSON序列化的图书对象

在这里插入图片描述

2.2 购买操作整体逻辑

当用户执行购买操作时,系统会按照以下流程进行处理:

  1. 参数校验 :Controller层对输入的图书ID和用户会话进行校验
  2. Redis库存检查 :Service层从Redis中查询对应图书的库存信息
  3. 库存扣减 :若库存充足,减少Redis中的库存数量
  4. 用户购买记录处理 :检查用户是否已购买过该图书
    • 首次购买:向用户特价图书表插入记录
    • 重复购买:更新用户特价图书表中的购买数量
  5. 返回结果 :根据操作结果返回成功或失败响应

在这里插入图片描述

2.3 取消购买操作整体逻辑

当用户执行取消购买操作时,系统会按照以下流程进行处理:

  1. 参数校验 :Controller层对输入的图书ID和用户会话进行校验
  2. 用户购买记录查询 :Service层查询用户特价图书表中该图书的购买记录
  3. 购买数量更新 :若存在购买记录且数量大于0,减少用户特价图书表中的购买数量
  4. Redis库存恢复 :增加Redis中对应图书的库存数量
  5. 返回结果 :根据操作结果返回成功或失败响应
    在这里插入图片描述

2.4 批量操作逻辑

批量购买和批量取消购买操作的整体逻辑类似,主要区别在于:

  1. 循环处理 :批量操作会遍历ID列表,逐个调用单个操作接口
  2. 异常处理 :批量操作中若某个单操作失败,会记录错误但继续处理后续操作
  3. 结果汇总 :最终返回整体操作结果,成功或失败
    在这里插入图片描述

2.5 分页查询逻辑

分页查询用户特价购物车的流程如下:

  1. 参数校验 :校验分页参数的合法性(当前页码、每页数量)
  2. 数据库查询 :根据分页参数查询用户特价图书表中的记录
  3. 数据处理 :将查询结果中的状态码转换为可读的状态名称(通过枚举类)
  4. 分页结果封装 :将查询结果和分页信息封装为PageResult对象
  5. 返回结果 :将分页结果返回给前端页面展示
    在这里插入图片描述

2.6 数据一致性保证

本系统在设计时考虑了数据一致性问题,主要通过以下方式保证:

  1. 缓存与数据库双重存储 :图书库存数据存储在Redis中,用户购买记录存储在数据库中
  2. 操作原子性 :购买和取消购买操作中,Redis操作和数据库操作保持一致
  3. 异常处理 :在操作失败时,通过异常捕获和处理确保不会出现数据不一致的情况
  4. 初始化同步 :系统启动时自动将数据库数据同步到Redis,保证初始数据一致

通过以上逻辑设计,系统实现了高效的图书购买与库存管理功能,同时保证了数据的一致性和系统的稳定性。
在这里插入图片描述

3. Redis配置

3.1 Redis配置类设计

在Spring Boot项目中,我们通过RedisConfig类来配置Redis相关参数,该类使用@Configuration注解标识为配置类,并通过@Bean注解注册RedisTemplate bean。以下是完整的配置代码:

@Configuration
public class RedisConfig {

    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory connectionFactory) {

        // 创建redisTemplate对象
        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();

        //设置连接工厂
        redisTemplate.setConnectionFactory(connectionFactory);

        // 创建json序列化工具
        GenericJackson2JsonRedisSerializer jsonRedisSerializer = new GenericJackson2JsonRedisSerializer();
        //设置Key的序列化
        redisTemplate.setKeySerializer(RedisSerializer.string());
        redisTemplate.setHashKeySerializer(RedisSerializer.string());
        //设置value的序列化
        redisTemplate.setValueSerializer(jsonRedisSerializer);
        redisTemplate.setHashValueSerializer(jsonRedisSerializer);

        return redisTemplate;

    }
}

在这里插入图片描述

3.2 序列化方式选择

在Redis配置中,序列化方式的选取至关重要,它直接影响数据在Redis中的存储格式和读取效率。本系统采用了以下序列化策略:

  1. Key的序列化 :使用RedisSerializer.string()对Key进行序列化,将Key转换为字符串格式,保证Key的可读性和唯一性
  2. Value的序列化 :使用GenericJackson2JsonRedisSerializer对Value进行序列化,将Java对象转换为JSON格式存储在Redis中
    • 优点:JSON格式具有良好的跨平台性和可读性,便于调试和问题排查
    • 缺点:相比二进制序列化,JSON序列化会增加一定的存储空间,但在可读性和兼容性上更有优势

3.3 RedisTemplate配置解析

RedisTemplate是Spring Data Redis提供的核心操作类,通过配置RedisTemplate可以自定义Redis的连接方式、序列化方式等。以下是配置中的关键步骤:

  1. 创建RedisTemplate实例 :通过构造函数创建RedisTemplate<String, Object>实例
  2. 设置连接工厂 :通过setConnectionFactory()方法注入RedisConnectionFactory,该工厂负责创建Redis连接
  3. 配置序列化器
    • 设置Key和HashKey的序列化器为字符串序列化器
    • 设置Value和HashValue的序列化器为JSON序列化器
  4. 返回配置好的RedisTemplate :将配置完成的RedisTemplate作为bean注册到Spring容器中

3.4 Redis配置的最佳实践

本配置遵循了以下Redis使用的最佳实践:

  1. 分开配置Key和Value的序列化 :Key使用字符串序列化保证可读性,Value使用JSON序列化保证对象完整性
  2. 使用连接工厂 :通过连接工厂管理Redis连接,提高连接的复用性和管理效率
  3. 模板化操作 :使用RedisTemplate封装Redis操作,避免直接操作Redis连接,提高代码的可维护性
  4. 通用Object类型 :将Value的类型设为Object,提高模板的通用性,支持存储不同类型的对象

3.5 Redis配置的扩展点

若需要对Redis配置进行扩展,可以考虑以下方向:

  1. 连接池配置 :在RedisConnectionFactory中可以配置连接池的大小、超时时间等参数
  2. Redis集群配置 :若需要支持Redis集群,可以配置集群节点信息
  3. 序列化方式优化 :若对性能要求极高,可以考虑使用二进制序列化(如JdkSerializationRedisSerializer)
  4. 缓存过期策略 :可以在存储数据时设置过期时间,避免无效数据长期占用内存

通过合理的Redis配置,本系统实现了高效的Redis操作,为高并发的库存管理和购买操作提供了性能保障。

4. 后端代码讲解

4.1 Controller层

Controller层作为前端请求的切入点,负责接收请求、参数校验、调用Service层处理业务逻辑,并将结果返回给前端。本系统的Controller层由SpecialDealNormalController类实现,主要包含以下几个核心方法:

4.1.1 购买图书方法
@RequestMapping("/buy")
public Result buy(Integer bookId, HttpSession session) {
    Result result = new Result();
    if (bookId == null) {
        result.setStatus(ResultStatus.FAIL);
        return result;
    }

    // 从session中提取用户
    UserInfo userInfo = (UserInfo) session.getAttribute(Constants.SESSION_USER_KEY);
    if (userInfo == null) {
        log.info("提取session中的userInfo失败");
        result.setStatus(ResultStatus.FAIL);
        return result;
    }

    boolean b = specialDealNormalService.buy(bookId, userInfo.getId());
    if (b == true) {
        result.setStatus(ResultStatus.SUCCESS);
        return result;
    }

    result.setStatus(ResultStatus.FAIL);
    return result;
}

该方法的处理流程:

  1. 校验图书ID是否为空
  2. 从Session中获取用户信息,校验用户是否登录
  3. 调用Service层的buy方法处理购买逻辑
  4. 根据Service层的返回结果设置响应状态
4.1.2 批量购买图书方法
@RequestMapping("/batchPurchaseSpecialBook")
public Result batchPurchaseSpecialBook(@RequestParam("idList") List<Integer> idList, HttpSession session) {
    log.info("----------------------batchPurchaseSpecialBook");
    Result result = new Result();

    if (idList == null || idList.size() == 0) {
        result.setStatus(ResultStatus.FAIL);
        return result;
    }
    try {
        for (Integer id : idList) {
            buy(id, session);
        }
    } catch (Exception e) {
        log.info("批量购买错误:" + e.getMessage());
        result.setStatus(ResultStatus.FAIL);
        return result;
    }

    result.setStatus(ResultStatus.SUCCESS);
    return result;
}

批量购买方法的特点:

  1. 校验ID列表是否为空或为空列表
  2. 遍历ID列表,逐个调用单个购买方法
  3. 使用try-catch捕获可能的异常,保证部分失败不影响整体流程
  4. 最终返回批量操作的整体结果
4.1.3 取消购买图书方法

```java
@RequestMapping("/noBuy")
public

文章整理自互联网,只做测试使用。发布者:Lomu,转转请注明出处:https://www.it1024doc.com/12746.html

(0)
LomuLomu
上一篇 6小时前
下一篇 4小时前

相关推荐

  • 🚀 2025年最新PyCharm激活码 & 永久破解教程(亲测有效,支持2099年)

    大家好!今天给大家带来一篇超详细的PyCharm破解教程,适用于2025年最新版本,亲测可用,激活后有效期直达2099年!🎉 无论是Windows、Mac还是Linux,无论你用的是PyCharm、IDEA还是其他Jetbrains全家桶,统统适用!💪 废话不多说,先上成功破解的截图,看看这效果👇 📥 下载PyCharm安装包 如果你已经安装好了PyChar…

    2025 年 6 月 6 日
    84000
  • 2024 GoLand最新激活码,GoLand永久免费激活码2025-02-05 更新

    GoLand 2024最新激活码 以下是最新的GoLand激活码,更新时间:2025-02-05 🔑 激活码使用说明 1️⃣ 复制下方激活码 2️⃣ 打开 GoLand 软件 3️⃣ 在菜单栏中选择 Help -> Register 4️⃣ 选择 Activation Code 5️⃣ 粘贴激活码,点击 Activate ⚠️ 必看!必看! 🔥 获取最新激活…

    2025 年 2 月 5 日
    38600
  • 2024 GoLand最新激活码,GoLand永久免费激活码2024-12-28 更新

    GoLand 2024最新激活码 以下是最新的GoLand激活码,更新时间:2024-12-28 ⚠️ 必看!必看! 🔥 获取最新激活码: 实时更新地址 👉 获取最新激活码 ⚠️ 重要提醒: 目前激活码容易被【秒封】,因为免费用户较多。建议使用我们提供的永久破解教程 点击查看 永久破解教程 支持JetBrains全系列产品(GoLand、PyCharm、Da…

    2024 年 12 月 28 日
    40800
  • 2025年最新PyCharm永久破解教程(亲测有效,支持2099年)🔥

    还在为PyCharm的激活问题发愁吗?😫 本教程将手把手教你如何永久破解PyCharm,让你的开发工具畅通无阻地使用到2099年!💪 适用于JetBrains全家桶(IDEA、PyCharm、DataGrip、Goland等),无论Windows、Mac还是Linux系统统统适用!✨ 先来看看最新PyCharm版本破解成功的实锤截图👇,有效期直接拉到2099…

    2025 年 5 月 14 日
    26500
  • 2024 WebStorm最新激活码,WebStorm永久免费激活码2025-02-14 更新

    WebStorm 2024最新激活码 以下是最新的WebStorm激活码,更新时间:2025-02-14 🔑 激活码使用说明 1️⃣ 复制下方激活码 2️⃣ 打开 WebStorm 软件 3️⃣ 在菜单栏中选择 Help -> Register 4️⃣ 选择 Activation Code 5️⃣ 粘贴激活码,点击 Activate ⚠️ 必看!必看! 🔥 …

    2025 年 2 月 14 日
    35600

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信