Java多线程:解决高并发环境下数据插入重复问题

2023-11-15

1.背景描述


应用框架:Spring + SpringMVC + Hibernate 
数据库:Oracle11g

一家文学网站向我系统推多线程低并发推送数据,我这边观察日志和数据库,发现有一个作者被存储了2次到数据库中。按照程序的编写逻辑,重复的数据是会被判断出来不被存储的。

2.原因分析

由于网络原因,客户可能连续推送了两条重复的数据,两条数据时间间隔非常小,因此导致了我们的

if(用户不存在)
{
    xxxxx
    存储用户到数据库
}
else
{
    重复推送,不采取任何措施
}
这个操作还没有执行完毕,第二条拥有相同数据的线程已经进入并通过了if的检验,导致数据库存储了两条相同的数据。后来我自己写了个100并发的多线程测试程序,发现100条相同数据中有40条被插入到了数据库里!天啦噜!!!因此确定了是多线程的并发导致了程序的判断逻辑失效。

3.解决思路:

    1) 在Author主表中对 身份证号 添加了唯一索引,现在Author主表不会出现重复数据了,如果连续推送客户会收到一条推送失败的提示信息。

    2) 但是AuthorOrg表(Author与AuthorOrg是一对多关系)依然会出现重复数据,想过添加siteId + userUniqueId的 联合唯一索引来解决,但是想到work表也会出现同样的问题,添加过多索引会导致DB占用空间无限增大,因此不采用。

    3) 考虑使用synchronized对方法添加同步锁,但是这样会导致其他正常数据的推送线程也被阻塞,影响效率。因此不采用。

    4) 使用对数据库添加行锁,实验发现还是会出现2条重复数据
        分析:
            理论上的结果应该是1条成功,149条失败。
            对数据库的select语句添加行锁必须作用于某条记录,但是第一次报送时,数据库中并没有这条数据,因此行锁根本没有加上,导致第二条数据成功异步使用select语句。
            第一次报送成功以后,数据库中有了这条数据,select语句成功的对这条记录添加了行锁,所以后边不会出现重复数据。因此此法不可用。

    5) 即想提高效率不对方法添加synchronized,又想保证数据准确性,最后使用synchronized(siteId + uid) 在Controller层加锁(保证了只有重复数据被加锁,在Controller使用的原因是因为事务会在Service调用完毕才被提交,我实验过在Service同步,150并发会出现2条重复数据,因为事务还没来得及提交)
    测试结果:测试了3次150并发  不到一秒的时间全部返回,结果1条登记成功,149条返回该作者已登记。

下一步:
    针对所有可能出现高并发问的接口进行调整。

4.提示

    这种加同步锁的方法在负载均衡下的多台应用服务器会失效!因为就算Spring保证了对象是单例的,但是多台服务器肯定是多个对象!因此synchronized将无效。解决方法是在数据库层对该对接公司的唯一记录加select锁,这样就能保证数据的不重复性,但是会降低该公司推送数据的效率(相当于逐条推送),但是公司与公司之间还是并行推送的。还有一个方法就是将业务逻辑写入存储过程,然后对存储过程加锁,这种方法太麻烦了,需求有变动就必须去修改存储过程,但是效率要比前者高得多。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Java多线程:解决高并发环境下数据插入重复问题 的相关文章

随机推荐

  • ISP_matlab

    确定输入是否为结构体数组字段 MATLAB isfield MathWorks 中国 对话框打开文件 获取路径和文件名 file path uigetfile raw RAW fid fopen fullfile path file htt
  • 百度通用翻译api使用

    官方api文档 http api fanyi baidu com api trans product apidoc springboot demo地址 https github com Blankwhiter translate 第一步 注
  • python web界面模板_Python简单轻量级Web Server模块Bottle

    Bottle 提示 使用此WEB服务器模块需要有基本的HTTP知识 简单 轻量级指的是 上手不难 容易使用 模块不大还能完成一般Web服务器的功能 Bottle是Python平台的轻量级Web Server 准确的说是HTTP Server
  • node.js在idea里运行

    Node js 是一种运行在 Chrome V8 JavaScript 引擎上的基于 JavaScript 的客户端运行时 JavaScript runtime 它可以用于构建网络应用程序和服务 在 Node js 中 你可以使用多种构建工
  • 从数据库字符串中获取数字部分,用于数据分析

    目录 前言 一 思路 1 获取字符串中的小数及整数部分 代码 效果 解析 2 获取字符串中数字部分 代码 效果 解析 二 总结 前言 在大数据时代 我们经常要分析很多非结构化的数据 同时也要分析很多非标准的数据 如 0 78吨 CYJ23w
  • 【数据结构 001】 定义

    数据 能被计算机处理 能被计算机识别 能输入计算机 数据元素 有一定意义的基本单位 数据项 数据元素的组成单位 认为是数据结构中最小组成单位 数据对象 具有相同性质的数据元素的集合 数据结构 存在特定关系的数据的集合 数据之间特定的结构关系
  • 线性表(C++实现)

    线性表的定义与基本操作 定义 具有相同数据类型的n个数据元素的有限序列 n是表长 当n为0的时候线性表是一个空表 如果用L命名线性表 那么其一般表示为 L a 1
  • 山谷 蓝桥杯

    问题描述 给定一个字母矩阵 如果矩阵中的某个位置不在四条边上 而且该位置上的字母小于其上下左右四个位 置的字母 则称为一个山谷 例如 对于如下矩阵 DDDDD CADCE FFFFA 共有两个山谷 位于第二行第二列和第四列 请注意第二行第三
  • 计算机网络-----网络编程

    网络编程 实战 网络基础 1 什么是计算机网络 2 什么是网络编程 3 网络编程中的主要问题 4 网络通信要素 5 通信协议分层思想 IP和端口号 1 IP 1 1定义 1 2IP的分类 2 端口号 2 1定义 2 2端口号的分类 网络通信
  • [转]Datagridview中的数据很多,加载完数据后滚动条自动到最下边的方法

    this dataGridView1 FirstDisplayedScrollingRowIndex this dataGridView1 Rows Count 1 转载于 https www cnblogs com aooyu archi
  • svn checkout 报 ‘svn: E000061: 执行上下文错误: Connection refused‘

    问题 svn E170013 svn E000061 svn svn checkout https xxx xxx xxx xxx 9443 svn project xxx svn E170013 Unable to connect to
  • php校验密码js,JS的密码强度校验正则表达式(附代码)

    这次给大家带来JS的密码强度校验正则表达式 附代码 使用JS的密码强度校验正则表达式注意事项有哪些 下面就是实战案例 一起来看一下 最近一直在做通行证项目 里面的注册模块中输入密码需要显示密码强度 低中高 今天就把做的效果给大家分享下 代码
  • 再谈二维数组,二级指针

    首先注意一个事实 是一个运算符 称 为 下 标 运 算 符 亦 称 变 址 运 算 符 我觉得应该是变址取内容 p n 恒 等于 p n 我们不能简单把指针看成地址 不要忽略掉数据类型 也就是说一个指针包含两方面 一个是地址 一个是数据类型
  • Nutanix是超融合厂商?原来我们都误会了……

    Nutanix是一家超融合厂商吗 是 也不是 中国的很多用户在初次接触Nutanix公司时 它已经在全球的超融合市场上声誉鹊起 并且被奉为超融合的鼻祖 所以人们先入为主地认为 Nutanix就是一家超融合厂商 作为一个新的细分产品市场的领导
  • Vijava 学习笔记之(VirtualMachineCloneSpec)

    VirtualMachineCloneSpec 指定虚拟机克隆规范 NAME TYPE DESCRIPTION config VirtualMachineConfigSpec 指定虚拟机的配置信息 customization Customi
  • http://www.baidu.com/cb.php?,搜索引擎中文网站提交登陆入口(09年完整汇总)

    7 雅虎中国 等同于易搜 提交 http search help cn yahoo com h4 4 html 8 TOM提交提交 http search tom com tools weblog log php 9 alltheweb 提
  • 数据结构六大排序详解(插入排序、希尔排序、选择排序、冒泡排序、快速排序、堆排序)

    数据结构六大排序详解 插入排序 希尔排序 选择排序 冒泡排序 快速排序 1 排序的概念 2 数据结构五大排序 2 1 插入排序 2 2 希尔排序 2 3 选择排序 2 4 冒泡排序 2 5 快速排序 2 5 1 hoare版本 左右指针法
  • 手把手教你开发微信小程序自定义底部导航栏

    手把手教你开发微信小程序自定义底部导航栏 一 创建微信小程序 二 配置底部菜单 1 配置app json文件 增加底部菜单 三 增加自定义底部菜单 1 app json配置文件 tabBar 增加 custom true 2 添加导航图标
  • ethercard php_PHP如何通过编程在服务端验证以太坊签名

    以太坊有一个非常强大的JavaScript生态系统 有一些很棒的开源项目 比如ethereumjs util 它提供了一个用以太坊帐户签名的即插即用功能 JavaScript的一个缺点是 在许多领域 它带来了安全问题 一个这样的安全风险是显
  • Java多线程:解决高并发环境下数据插入重复问题

    1 背景描述 应用框架 Spring SpringMVC Hibernate 数据库 Oracle11g 一家文学网站向我系统推多线程低并发推送数据 我这边观察日志和数据库 发现有一个作者被存储了2次到数据库中 按照程序的编写逻辑 重复的数