springboot整合redis解决订单重复请求的问题

springboot整合Redis分布式锁最佳实践 什么是分布式锁 在单机环境中,一般在多并发多线程场景下,出现多个线程去抢占一个资源,这个时候会出现线程同步问题,造成执行的结果没有达到预期。我们会用线程间加锁的方式,比如synchronized,lock,volatile,以及JVM并发包中提供的其他工具类去处理此问题。 但是随着技术的发展,分布式系统的出现,各个应用服务都部署在不同节点,由各自的JVM去操控,资源已经不是在 线程 之间的共享,而是变成了 进程 之间的共享,以上解决线程同步问题的办法已经无法满足。 因此,引入了分布式锁的概念。 分布式锁,既 阅读详情

实现思路:将请求的json数据,去除一些可变字段,将key升序排序,拼接成字符串并进行md5加密,再拼接一些用户信息,这样相同的请求参数得到的加密串必然一致,将此字符串作为key,存入redis,设置过期时间为1秒,一般重复提交都是在1000ms以内;

代码部分
package com.wang.learn.cloudredis.controller;

import com.alibaba.fastjson.JSONObject;
import com.wang.learn.cloudredis.entity.Book;
import com.wang.learn.cloudredis.utils.ReqDedupHelper;
import org.springframework.data.redis.connection.RedisStringCommands;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.types.Expiration;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.validation.Valid;

/**
 * ClassName RedisController
 * Description
 *
 * @author wang
 * Date 2021/6/19 10:48
 */
@RestController
@RequestMapping("/redis")
public class RedisController {


    @Resource
    private RedisTemplate<String, Object> stringRedisTemplate;

    @RequestMapping("/repeat")
    public Object repeat(@RequestBody @Valid Book book){
        //用户
        String userId= "12345678";
        //接口名
        String method = "pay";
        //计算请求参数摘要,其中剔除里面请求时间的干扰
        String dedupMD5 = ReqDedupHelper.dedupParamMD5(JSONObject.toJSONString(book),"time");
        String KEY = "dedup:U=" + userId + "M=" + method + "P=" + dedupMD5;
        // 1000毫秒过期,1000ms内的重复请求会认为重复
        long expireTime =  1000;
        long expireAt = System.currentTimeMillis() + expireTime;

        String val = "expireAt@" + expireAt;
        // 如果key不存在,set并返回true;如果key存在,不做操作返回false
        Boolean firstSet = stringRedisTemplate.opsForValue().setIfAbsent(key, val, expireTime, TimeUnit.MILLISECONDS);

        final boolean isConsiderDup;
        if (firstSet != null && firstSet) {
            return book;
        } else {
            return "订单重复!";
        }
    }

}

package com.wang.learn.cloudredis.utils;

import com.alibaba.fastjson.JSON;
import com.wang.learn.cloudredis.entity.Book;
import lombok.extern.slf4j.Slf4j;

import javax.xml.bind.DatatypeConverter;
import java.security.MessageDigest;
import java.util.Arrays;
import java.util.List;
import java.util.TreeMap;

/**
 * ClassName Req
 * Description
 *
 * @author wang
 * Date 2021/6/19 10:29
 */
@Slf4j
public class ReqDedupHelper {

    /**
     *
     * @param reqJSON 请求的参数,这里通常是JSON
     * @param excludeKeys 请求参数里面要去除哪些字段再求摘要(如时间戳字段)
     * @return 去除参数的MD5摘要
     */
    public static String dedupParamMD5(final String reqJSON, String... excludeKeys) {
        String decreptParam = reqJSON;

        TreeMap paramTreeMap = JSON.parseObject(decreptParam, TreeMap.class);
        if (excludeKeys!=null) {
            List<String> dedupExcludeKeys = Arrays.asList(excludeKeys);
            if (!dedupExcludeKeys.isEmpty()) {
                for (String dedupExcludeKey : dedupExcludeKeys) {
                    if(paramTreeMap.containsKey(dedupExcludeKey)){
                        paramTreeMap.remove(dedupExcludeKey);
                    }
                }
            }
        }

        String paramTreeMapJSON = JSON.toJSONString(paramTreeMap);
        String md5deDupParam = jdkMD5(paramTreeMapJSON);
        log.debug("md5deDupParam = {}, excludeKeys = {} {}", md5deDupParam, Arrays.deepToString(excludeKeys), paramTreeMapJSON);
        return md5deDupParam;
    }

    private static String jdkMD5(String src) {
        String res = null;
        try {
            MessageDigest messageDigest = MessageDigest.getInstance("MD5");
            byte[] mdBytes = messageDigest.digest(src.getBytes());
            res = DatatypeConverter.printHexBinary(mdBytes);
        } catch (Exception e) {
            log.error("",e);
        }
        return res;
    }

    public static void main(String[] args) {
        Book book = new Book();
        book.setId(1);
        book.setCount(2);
        book.setName("java编程思想");
        book.setTime(System.currentTimeMillis());

        String key = dedupParamMD5(JSON.toJSONString(book), "time", "456");
        System.out.println(key);


    }

}

源码参考 https://gitee.com/wangLi1997/spring-cloud-learn cloud-redis模块

Java面试技巧:SpringBoot与Redis实战解析 Java作为企业级开发的主流语言,其技术栈的深度与广度直接影响面试表现。SpringBoot通过自动装配机制简化了配置,核心原理涉及@EnableAutoConfiguration注解和条件装配,这种设计模式显著提升了开发效率。Redis作为高性能缓存数据库,在分布式系统中解决并发与数据一致性问题,其跳跃表实现和持久化策略是面试高频考点。结合当前热词SpringBoot和Redis,本文通过典型场景拆解,展示如何从原理层理解技术价值,并应用于电商订单系统等实际业务场景,帮助开发者构建扎实的Java知识体系与 阅读详情

相关推荐

UniApp X 网络请求避坑指南:从 JS 到 UTS 的 JSON 数据处理全解析

摘要:UniAppX开发中处理JSON数据时,UTS强类型特性要求开发者改变JS习惯。本文对比两种主流方案:1)UTSJSONObject通过keypath访问数据,兼容JS但缺乏类型提示;2)type+泛型方案,通过定义数据类型实现强类型校验和智能提示,推荐用于固定数据结构。文章详细演示了两种方式的具体实现、转换方法及实战案例,并提供了类型定义技巧和注意事项,帮助开发者编写更稳定高效的跨平台应用。

归梦工作室 2791

SpringBoot解决用户重复提交订单(方式一:通过唯一索引实现)

1.由于用户误操作,多次点击表单提交按钮2.由于网速等原因造成页面卡顿,用户重复刷新提交页面3.黑客或恶意用户使用 postman 等网络工具,重复恶意提交表单这些情况都可能会导致表单重复提交,造成数据重复,比如订单表,重复提交订单数据所造成的问题,可能不仅仅是数据上的混乱,也会造成业务混乱。那么问题来了,我们该如何防止用户重复提交数据呢?方案实践如下!

weixin_47316183的博客 3313

Ubuntu20.04复现instant-ngp,自建数据集,导出mesh

本次仅仅记录一下自己复现instant-ngp的过程,如果里面的参考有冒犯到原博主请联系我删除,本人也是nerf的小白一枚,可以一起交流学习神经辐射场,希望大家在复现instant-ngp的时候少走一些坑,情况允许下可以去复现一下npg-pl和nerfStudio,最后希望大家一起进步。看到一些博主说葵司的npg_pl也不错,而且葵司是台湾人,在youtube上也有讲解的视频。渲染的效果还是可以的,相对于源码来说还是有点模糊,我一些参数也没有设置,直接就拉进来进行渲染,速度是非常快的。

weixin_59961223的博客 9453

Spring Boot 整合支付宝支付(新版 Alipay Easy SDK 2.0)

接入准备 介入前的准备工作可以参考我的这篇博文: jsp对接支付宝支付接口,实现网站在线支付 如果使用的是旧版的 SDK,请移步 Spring Boot 整合支付宝 网页导航 由于网站改动较大,所以在此记录一下 SDK 的位置。 进入支付宝开放平台首页,点击 文档 => 网页&移动应用 然后点击 快速示例 DEMO 搭建项目 以下内容全部来自支付宝官方文档: https://opendocs.alipay.com/open/54/00y8k9 API 文档: https://

虚言假面的博客 1万+

Synopsys安装教程Ubuntu22.04版本

在Ubuntu22版本上安装Synopsys等系列工具,安装DC,VCS等等

qq_59529218的博客 5731

STK中的传感器与通信组件:雷达、发射机、接收机与天线的协同建模

本文深入解析了STK软件中传感器、雷达、发射机、接收机与天线的协同建模方法。通过构建一个完整的卫星对地数传系统实例,阐述了各组件如何分工协作,实现从几何指向到射频链路的高保真仿真,为复杂航天通信与探测系统的设计与分析提供了高效、灵活的解决方案。

weixin_29271263的博客 273

SpringBoot解决用户重复提交订单(方式二:通过Redis实现)

在上一篇文章中,我们详细的介绍了对于下单流量不算高的系统,可以通过请求唯一ID数据表增加唯一索引约束这种方案来实现防止接口重复提交!随着业务的快速增长,每一秒的下单请求次数,可能从几十上升到几百甚至几千。面对这种下单流量越来越高的场景,此时数据库的访问压力会急剧上升,上面这套方案全靠数据库来解决,会特别吃力!对于这样的场景,我们可以选择引入缓存中间件来解决,可选的组件有 redis、memcache 等。下面,我们以引入Redis缓存数据库服务器,向大家介绍具体的解决方案!

weixin_47316183的博客 2812

ROS水下仿真神器uuv_simulator:从零搭建水下机器人测试环境(附Gazebo配置全流程)

本文详细介绍了如何使用ROS和uuv_simulator从零搭建水下机器人仿真测试环境,包括Gazebo配置全流程。通过系统环境准备、水下世界构建、机器人模型定制开发等步骤,帮助开发者在虚拟海洋环境中高效验证算法,大幅降低研发成本。特别适合水下机器人研发人员参考。

ujm5678901的博客 264

Spring Boot + Redis 解决重复提交问题,还有谁不会

.markdown-body { line-height: 1.75; font-weight: 400; font-size: 16px; overflow-x: hidden; color: rgba(37, 41, 51, 1) } .markdown-body h1, .markdown-body h2, .markdown-body h3, .markdown-body h4, .ma...

程序员小明1024 239

从养殖场到科技前沿:YOLOv11+OpenCV精准计数鸡蛋与鸡

YOLOv11结合OpenCV技术,精准识别和计数鸡蛋与鸡,广泛应用于养殖场、市场监控和自动化包装。通过深度学习与计算机视觉,提升农业生产效率,让智能化管理更简单高效。

专注于深入研究多种编程语言,以实战为导向,逐步拓展开发技能,提升工程化编码和思维能力,展现无敌技术实力。 1208

手把手打通全流程:在华为昇腾310/Atlas 200DK上实现深度学习模型从移植到部署

通过以上步骤,你已成功在华为昇腾310 Atlas 200DK上完成深度学习模型的移植与推理。这一流程可复用到目标检测、语义分割等其他任务,快去尝试将自己的AI模型部署到昇腾设备上,打造属于你的边缘智能应用吧!上部署深度学习模型,这篇教程将带你走完从模型转换到推理运行的完整流程。无需担心技术壁垒,我们以通俗易懂的方式拆解每一步,让你轻松在昇腾嵌入式设备上实现AI应用。是专为边缘AI设计的高性能处理器,Atlas 200DK是其开发板形态,能高效运行图像分类、目标检测等深度学习任务。

FJN110的博客 183

基于SpringBoot的秒杀商品系统

秒杀服务

乐嘉工作室 659

【YOLOv8改进-注意力机制】BRA(bi-level routing attention ):双层路由注意力

【YOLOv8改进-注意力机制】BRA(bi-level routing attention ):双层路由注意力我们提出了一种新颖的动态稀疏注意力机制,通过双层路由实现更加灵活且具有内容感知的计算分配。

专注于图像领域,主要研究内容包括计算机视觉和深度学习,特别是在图像分类、目标检测和图像生成等方面有深入的研究和实践经验。 3173

关于使用Redis解决用户重复提交订单的问题

问题场景,秒杀活动,或者其他情况下,用户多次点击下单,导致发生了订单重复提交的问题 根据这问题,结合Redis的 Redis Incr 命令将 key 中储存的数字值增一。 如果 key 不存在,那么 key 的值会先被初始化为 0 ,然后再执行 INCR 操作。 如果值包含错误的类型,或字符串类型的值不能表示为数字,那么返回一个错误。 本操作的值限制在 64 位(bit)有符号数字表示之内。 这个特性,我们就有了一个解决用户重复提交订单的问题,案例代码如下 package com.

这里没有简介 2236

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

springboot整合redis和kafka,分析并实现高并发秒杀业务

文章目录1.前言2.秒杀业务分析3.解决方案3.1 拦截部分请求3.2 引入缓存3.3 超卖问题4.秒杀逻辑简单实现及优化4.1 项目搭建4.2 秒杀代码4.2.1 创建实体类4.2.2 创建dao4.2.3 业务逻辑层4.2.4 秒杀接口4.2.4.1 数据库层面处理超卖问题4.2.4.2 加锁4.2.5 秒杀接口优化4.2.6 用户不能重复秒杀问题4.2.7 秒杀接口订单异步处理优化 1.前言...

右手边的流年 5172

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

某个订单项目记录,涉及MQ消息处理、分布式问题、幂等性等问题解决设计

在电商订单中心等场景中,使用消息队列可以解决登录拦截、接口幂等性、分布式事务等问题。同时,需要注意消息队列可能会出现的消息积压、丢失、重复等问题,并采取相应的解决方案。此外,还有分布式事务问题解决,最大消息通知事务等等相关架构设计。

探索技术与实践的旅程,分享编程经验与工具使用心得,助力开发者提升技能。 2000

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

SpringBoot3整合Redis消息队列避坑指南

讲完案例、问题和专家建议,其实技术分享最有价值的还是大家的实践经验。我想问问你:你在项目中用过 Redis 做消息队列吗?有没有遇到过 “消息丢失”“重复消费” 这类问题?你是怎么解决的?或者你觉得 Redis 消息队列和 RabbitMQ、Kafka 比,有哪些优势和不足?欢迎在评论区留言分享你的经历,咱们一起交流避坑技巧。

Sgfcgg的博客 981

Redis应用之一自增编号

淘宝订单编号 827768001755267512 ,共18位,其中最后6位是不变的,这个订单编码变更过几次,现在具体规则我也不太清楚,原来和淘宝的商品中心打过一些交道,好像还下载代码,不管是表结构还是代码架构扩展性做得很好,不像商品发布Shell平台那么乱。Redis是IO多路复用单线程模型,一个CPU绑定了一块内存区域,所有客户端的命令都会放入队列,然后逐条执行,所以Redis INCR命令本身是原子性的,它能保证每次返回的结果不会是相同的值,可以做为原子性计数器。订单编码要保证绝对不能重复。

程序员青菜学厨记 867

springboot 整合 redis(一)

springboot 整合 redis(一) 每天点滴努力,成就编程路 描述 前言:redis是一个高性能键值对(key-value)NOSQL数据库。 优点:性能极高 – Redis能支持超过 100K+ 每秒的读写频率。 丰富的数据类型,Strings, Lists, Hashes, Sets 及 Ordered Sets 数据类型操作。 缺点:数据库容量受到物理内存的限制,不能用作海量数据的高性能读写。 redis应用场景 1.热点数据缓存。针对经常需要被查询,而不经常性被修改或者删除的数据。

遥不可及的博客 359

Mq重复消费(幂等)解决方案

Mq重复消费(幂等)解决方案,以上都是我最近工作上的学习总结和思考,如果有什么更好的方案欢迎大家评论区讨论~~最后附上git仓库地址:https://gitee.com/himatengfei/mq-resolve-idempotent。

qq_48575500的博客 1775

SpringBoot整合Redis实现优惠券秒杀服务

Springboot整合Redis实现优惠券秒杀服务

qq_45949914的博客 1865

基于SpringBoot的产品订单管理系统(源码+讲解视频+LW)

在市场竞争激烈、消费者需求日益多样化的当下,传统产品订单管理模式存在流程冗长、数据分散、响应迟缓等弊端。人工处理订单易出现错漏,跨部门沟通不畅导致订单进度跟踪困难,无法及时应对客户需求变更;库存、生产与订单数据脱节,常引发库存积压或供货延迟,增加企业运营成本。据行业数据显示,低效的订单管理可使企业订单处理周期延长 30% 以上,客户满意度下降 25% 。基于 SpringBoot 的产品订单管理系统应运而生,旨在打破信息壁垒,实现订单全生命周期数字化管理。该系统整合订单创建、审核、分配、生产跟踪、物流监控及

专注于大学生项目实战开发,讲解,毕业答疑辅导,高校老师/讲师/同行合作。以及产品测评宣传、工具推广等合作。全网粉丝30万+,优快云特邀博主,Java新星计划多届导师,掘金/知乎/华为云/阿里云/51CTO等平台优质创作者。 1101

电商订单超时取消:SpringBoot+Quartz实战

电商系统中,订单超时自动取消是一个经典场景。比如用户下单后30分钟内未支付,系统需要自动释放库存并标记订单失效。手动处理既不实时也容易遗漏,而定时任务框架能完美解决这个问题。整个开发过程无需操心环境配置,遇到问题还能实时查看执行日志。对于需要持续运行的后台服务,这种开箱即用的体验确实省心。使用Spring接管Quartz的Bean管理,避免手动实例化。通过JPA的@Modifying注解优化批量更新性能。记录最后修改时间用于排查问题。

IndigoNight21的博客 998

【实战项目】基于SpringBoot 天猫商城基于前后端分离+SpringBoot+BootStrap、Vue.js、JQuery+JPA+Redis

SpringBoot天猫商城整站 基于前后端分离+SpringBoot+BootStrap、Vue.js、JQuery+JPA+Redis

Tyler的博客 1万+

Springboot + redis + 注解 + 拦截器来实现接口幂等性校验

Springboot + redis + 注解 + 拦截器来实现接口幂等性校验 1.SpringBoot 整合篇 2.手写一套迷你版HTTP服务器 3.记住:永远不要在MySQL中使用UTF-8 4.Springboot启动原理解析 一、概念 幂等性, 通俗的说就是一个接口, 多次发起同一个请求, 必须保证操作只能执行一次比如: 订单...

weixin_30314631的博客 198
上一篇: dependencyManagement与dependencies区别
下一篇: java登陆页实现前端RSA加密,后端RSA解密
宁漂打工仔
博客等级 码龄9年 1万+粉丝 153原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

宁漂打工仔

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值