广告
返回顶部
首页 > 资讯 > 精选 >怎么解决java并发请求下数据插入重复问题
  • 472
分享到

怎么解决java并发请求下数据插入重复问题

2023-06-25 14:06:26 472人浏览 独家记忆
摘要

本篇内容介绍了“怎么解决java并发请求下数据插入重复问题”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!前言前段时间发现数据库里经常会存在两

本篇内容介绍了“怎么解决java并发请求下数据插入重复问题”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

前言

前段时间发现数据库里经常会存在两条相同的用户数据,导致数据查询异常。查了原因,发现前端微信小程序在授权登录时,有时会出现同时发送了两条一模一样的请求(也就是常说的并发)。虽然后端代码有做防重复的判断,但是避免不了并发时候的重复性操作。于是就开始考虑并发的解决方案,解决方案有很多,从拦截请求到数据库层面都可以入手。

我们采用了对请求报文生成摘要信息+Redis分布式的方案。运行了一段时间,功能很可靠,代码也很简洁。于是上来做下记录以便后续参考。

解决方案说明:

系统架构用的Spring Boot,定义一个Filter过滤器对请求进行过滤,然后对请求报文生成摘要信息并设置Redis分布式锁。通过摘要和锁判断是否为同一请求。

分布式锁工具

public class ContextLJ {private static final Integer JD = 0;    public static boolean lock(String sign, String tiD) {    synchronized (JD) { // 加锁    Cache<String> cache = CacheManager.getCommonCache(sign);    if(cache == null || StringUtils.isBlank(cache.getValue())) {    CacheManager.putCommonCacheInfo(sign, tiD, 10000);    return true;}    return false;    } }     public static boolean checklock(String sign, String tiD){  Cache<String> cache = CacheManager.getCommonCache(sign);  String uTid = StringUtils.replace(cache.getValue(), "\"", "");  return tiD.equals(uTid);  }     public static void clent (String sign, String tiD){    if (checklock(sign, tiD)) {    CacheManager.clearOnly(sign);    }  }     public static String getSign(ServletRequest request){    // 此工具是将 request中的请求内容 拼装成 key=value&key=value2 的形式 源码在线面    String sign = null;    try {    Map<String, String> map =  getRequstMap((httpservletRequest) request);    // 生成摘要    sign = buildRequest(map);    } catch (Exception e) {    e.printStackTrace();    }    return sign;  }    public static Map<String, String> getRequstMap(HttpServletRequest req) throws Exception{     Map<String,String> params = new HashMap<String,String>();     params.put("uri", req.getRequestURI());    Map<String, String[]> requestParams = req.getParameterMap();    for (Iterator<String> iter = requestParams.keySet().iterator(); iter.hasNext();) {      String name = (String) iter.next();      String[] values = (String[]) requestParams.get(name);      String valueStr = "";      for (int i = 0; i < values.length; i++) {        valueStr = (i == values.length - 1) ? valueStr + values[i] : valueStr + values[i] + ",";      }      params.put(name, valueStr);    }    return params;}   private static String buildRequest(Map<String, String> map) { List<String> signList = new ArrayList<>(); for(Entry<String, String> entry : map.entrySet()) { signList.add(entry.geTKEy() + "=" + entry.getValue()); } String sign = StringUtils.join(signList, "&"); return DigestUtils.md5Hex(sign);}}

在过滤器实现请求拦截

@Slf4j@Componentpublic class MyFilter implements Filter{@Overridepublic void init(FilterConfig filterConfig) throws ServletException {}@Overridepublic void doFilter(ServletRequest request, ServletResponse myResp, FilterChain chain) throws IOException, ServletException {HttpServletRequest req = (HttpServletRequest) request;Boolean isDict = StringUtils.contains(req.getRequestURI(), "/dict/getDatas");Boolean isFile = StringUtils.contains(req.getRequestURI(), "/files/file");if(isDict || isFile) {chain.doFilter(request, myResp); // 查询数据字典或者文件,直接放行return;}String sign = "sign_" + ContextLJ.getSign(request); // 生成摘要    String tiD = RandomUtils.randomCode(3) + "_" + Thread.currentThread().getId(); // 当前线程的身份    try {     if (!ContextLJ.lock(sign, tiD)) {    Map<String,String> map = ContextLJ.getRequstMap((HttpServletRequest)request);    log.warn("放弃相同并发请求【" + sign+ "】【" + tiD+"】"+JSON.tojsONString(map));    frequentlyError(myResp);    return;    }    if (!ContextLJ.checklock(sign, tiD)) {    Map<String,String> map = ContextLJ.getRequstMap((HttpServletRequest)request);      log.warn("加锁验证失败 【" + sign+ "】【" + tiD+"】"+JSON.toJSONString(map));      frequentlyError(myResp);      return;    }    chain.doFilter(request, myResp); // 放行    } catch (Exception e) { // 捕获到异常 进行异常过滤      log.error("", e);      myResp.getWriter().write(JSON.toJSONString(apiRs.asError("服务器繁忙,请重试")));    } finally {    ContextLJ.clent(sign, tiD);    }}@Overridepublic void destroy() {}private void frequentlyError(ServletResponse myResp) throws IOException {  ((HttpServletResponse) myResp).setHeader("Content-type", "text/html;charset=UTF-8");  myResp.getWriter().write(JSON.toJSONString(ApiRs.asError("稍安勿躁,不要频繁请求")));}}

“怎么解决java并发请求下数据插入重复问题”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注编程网网站,小编将为大家输出更多高质量的实用文章!

--结束END--

本文标题: 怎么解决java并发请求下数据插入重复问题

本文链接: https://www.lsjlt.com/news/305489.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • 怎么解决java并发请求下数据插入重复问题
    本篇内容介绍了“怎么解决java并发请求下数据插入重复问题”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!前言前段时间发现数据库里经常会存在两...
    99+
    2023-06-25
  • java并发请求下数据插入重复问题的解决方法
    目录前言分布式锁工具类在过滤器实现请求拦截总结前言 前段时间发现数据库里经常会存在两条相同的用户数据,导致数据查询异常。查了原因,发现前端微信小程序在授权登录时,有时会出现同时发送了...
    99+
    2022-11-12
  • python线程池并发请求数据问题怎么解决
    在Python中,可以使用concurrent.futures模块中的ThreadPoolExecutor类来创建线程池,并发处理请...
    99+
    2023-10-26
    python
  • golang百万并发请求问题怎么解决
    在Go语言中,可以使用goroutine和channel来实现百万并发请求的处理。以下是一种解决方案的示例: 创建一个请求队列,将...
    99+
    2023-10-27
    golang
  • 基于java HashMap插入重复Key值问题怎么解决
    这篇“基于java HashMap插入重复Key值问题怎么解决”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“基于j...
    99+
    2023-07-05
  • Linq插入数据问题怎么解决
    这篇文章主要讲解了“Linq插入数据问题怎么解决”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Linq插入数据问题怎么解决”吧!今天用Linq插入数据,总是插入错误,说某个主键字段不能为空,...
    99+
    2023-06-17
  • SQLServer中怎么防止并发插入重复数据
    SQLServer中怎么防止并发插入重复数据,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。SQLServer中防止并发插入重复...
    99+
    2022-10-18
  • java高并发下脏读问题怎么解决
    在Java高并发下解决脏读问题可以通过使用锁机制或者使用线程安全的数据结构来实现。1. 使用锁机制:可以使用synchronized...
    99+
    2023-08-23
    java
  • Mysql批量插入数据时该如何解决重复问题详解
    目录前言一、三种方法二、细节2.1、insert ignore into2.2 、insert into ... on duplicate key update2.3、replace into三、总结前言 当数据库中存量...
    99+
    2022-11-10
  • PHP 防抖技术:解决高并发场景下的数据重复提交问题
    导言:在高并发场景中,用户可能会频繁点击按钮或提交表单,这就导致服务器收到多次相同的请求,从而可能造成数据的重复提交。针对这一问题,我们可以采取一种被称为“防抖”的技术来解决。本文将介绍PHP中的防抖技术以及具体的代码示例,旨在帮助开发者们...
    99+
    2023-10-21
    高并发 防抖技术 数据重复提交
  • 怎么解决PHP插入数据库乱码问题
    这篇文章主要介绍“怎么解决PHP插入数据库乱码问题”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“怎么解决PHP插入数据库乱码问题”文章能帮助大家解决问题。一、检查数据库字符集在开始解决问题之前,首先...
    99+
    2023-07-05
  • SpringBoot @PostMapping接收HTTP请求的流数据问题怎么解决
    这篇文章主要讲解了“SpringBoot @PostMapping接收HTTP请求的流数据问题怎么解决”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“SpringBoot ...
    99+
    2023-07-05
  • 系统高吞吐量下的数据库重复写入问题分析解决
    目录问题分析数据库上解决从程序上保证数据不重复总结问题分析 为了提高系统的吞吐量,很多环节下对于数据库的写入是多线程,甚至是多进程的。为了保证写入成功,在很多情况下需要多次重试。这就...
    99+
    2022-11-13
  • Mysql怎么数据库平滑扩容解决高并发和大数据量问题
    本篇内容主要讲解“Mysql怎么数据库平滑扩容解决高并发和大数据量问题”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Mysql怎么数据库平滑扩容解决高并发和大数据量问题”吧!1 停机方案发布公告...
    99+
    2023-06-30
  • 怎么解决MySQL分页时使用 limit+order by出现数据重复的问题
    这期内容当中小编将会给大家带来有关怎么解决MySQL分页时使用 limit+order by出现数据重复的问题,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。0 问题描述在...
    99+
    2022-10-19
  • 怎么解决MySQL命令窗口中文乱码或插入中文数据失败的问题
    这篇文章主要介绍“怎么解决MySQL命令窗口中文乱码或插入中文数据失败的问题”,在日常操作中,相信很多人在怎么解决MySQL命令窗口中文乱码或插入中文数据失败的问题问题上存在疑惑,小编查阅了各式资料,整理出...
    99+
    2022-10-18
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作