并发insert情况下会发生重复的数据插入问题
1.背景
用多线程接收推送的订单数据,把接收的订单数据存到一个表中,实现的需求是:如果接收的订单消息在数据库中已经存在,那么执行update操作;如果没有存在,那么执行insert操作
代码逻辑:
if(该订单在数据库表中存在){
update();
}else{
insert();
}
线程启动后,发现:数据库表中有两条oderid相同的记录
通过查看日志发现:
两个线程相差时间极端,各自收到了同一个订单的推送消息,在执行数据库insert或update时,都判断出该订单在数据库表中不存在,所以都执行insert操作,造成数据库表中有两条orderid相同的记录
2.解决方案
synchronized同步代码块即加同步锁,synchronized同步代码块的功能:
1)、当A线程访问对象的synchronized代码块的时候,B线程依然可以访问对象方法中其余非synchronized块的部分
2)、当A线程进入对象的synchronized代码块的时候,B线程如果要访问这段synchronized块,那么访问将会被阻塞
if(该订单在数据库表中存在){
update();
}else{
synchronized(this){
if(该订单在数据库表中存在){
update();
}else{
insert();
}
}
}
上面用synchronized同步代码块解决了在单点服务器中涉及到的并发问题,但是synchronized同步代码块在部署到多台服务器会失效,因为假设A机器在在执行数据库insert,判断出数据库中没有某个订单的数据,同时此刻B机器也判断出没有该订单数据,两台机器都进行insert操作,造成数据库中有重复的订单数据
3.多台服务器相互之间的并发导致有重复的订单数据问题解决
解决方案:
在数据库层面,用unique唯一性约束来保证数据的数据库表orderid的唯一性.
添加了唯一性约束后,假设A机器insert成功了,那么B机器再insert的时候会违反唯一性约束,报InvocationTargetException这个异常,捕获该异常后,进行update操作
if (该订单在数据库表中存在) {
update();
} else {
synchronized (this) {
if (该订单在数据库表中存在) {
update();
} else {
try {
insert();
} catch (InvocationTargetException e) {
update();
}
}
}
}
来源:https://blog.csdn.net/lululove19870526/article/details/60592981
并发insert情况下会发生重复的数据插入问题相关推荐
- mysql基础14(关于mysql数据库在没有主键情况下去除重复数据办法)
关于mysql数据库在没有主键情况下去除重复数据办法 约定 表名:mat 根据 cat 字段去重 新增加主键为 id 步骤 1.为mat新增一列自增主键 alter table mat add col ...
- Goroutine调度时机-什么时候和什么情况下会发生调度?
原文地址:Goroutine调度时机-什么时候和什么情况下会发生调度? Go调度器会在以下三种情况对goroutine进行调度: goroutine执行某个操作因条件不满足需要等待而发生的调度. go ...
- 在高并发的情况下,利用redis来处理库存超卖和遗留问题
在高并发的情况下,利用redis来处理库存超卖和遗留问题 首先现在redis中放上商品的库存数量为100间商品,在初始化一个set集合用于放秒杀成功的用户id,本用例先放进去一个id=10000的用户 ...
- 什么情况下会发生full Gc?如何排查频繁发生full Gc的原因?
GC就是Java的垃圾回收机制,要了解什么情况下会发生GC(即GC得触发条件),我们需要先了解JVM的内存模型结构,之前一篇文章已经详细讲解了Jvm的内存模型结构,而通常来说,GC主要针对的是堆(ja ...
- cassss服务未启动_Mysql无法启动情况下,如何恢复数据呢?
本文适用于,mysql无法启动,但数据文件未丢失的情况. Mysql因意外情况,导致无法启动,数据库未做备份的情况下,如何将数据迁移至其他数据库中. 原数据库地址:192.168.1.100(以下简称 ...
- Excel(WPS)使用VBA,不打开文件情况下提取其他工作簿数据
Excel(WPS)使用VBA,不打开文件情况下提取其他工作簿数据 提取函数,返回提取到的值 使用示例 在不打开工作簿的情况下,VBA读取其他工作簿数据 很多方法需要打开才能提取,如果没打开会显示错误 ...
- Android 无 EditText 情况下接受扫码枪扫描数据
2019年04月12日更新,根据评论区反馈,可能不是很好用(但是我当时用的时候就是这么实现的),可以选择性尝试 Android 无 EditText 情况下接受扫码枪扫描数据 简单无脑! 去下载个 J ...
- 键盘上哪个键是插入建_如何在没有插入键的情况下按键盘上的“插入”?
键盘上哪个键是插入建 Finding a keyboard that has all the features you want can be a bit of a task at times, bu ...
- mysql 并发避免锁表_MYSQL锁表的用法,防止并发情况下的重复数据
项目中有些使用的redis存储,当对redis进行rehash的时候感觉是比较麻烦的.于是写了个简单的读取redis到数据库的关键方法.仅供参考. package com.redis.web; imp ...
最新文章
- python matplotlib散点图-python matplotlib从函数更新散点图
- [Done]Spring @Pointcut 切点调用不到(SpringAOP嵌套方法不起作用) 注意事项
- .net 下语音合成
- ArcGIS 9.2 Server Pack 5 蓄势待发
- Spring MVC Ajax返回中文乱码
- 【转】刨根究底字符编码之十四——UTF-16究竟是怎么编码的
- Git - git tag - 查看当前分支 tag 版本说明
- 学习记录-操作系统知识(1)
- PHP整站迁移空间,Discuz! X2.5 整站搬家迁移升级教程
- 注册测绘师学习笔记(一)
- OpenCV库下载安装使用方法
- 微信小程序双击底部导航栏刷新页面
- JDK下载安装及环境变量配置的图文教程(详解)
- 计算机等考网络真题2018,2018年网络管理员考试试题及答案
- Word 题注重新编号
- python条件判断《X战警:逆转未来》
- 读《刻意练习》后感,与原文好句摘抄
- 真实评测 rtx3080ti对比rx6800xt选哪个好
- docker logs
- 物资学院、草房、常营点过的外卖总结
热门文章
- 看代码的软件_软件著作权申请中常见的补正问题及解决方式
- R语言——导入Excel表格数据方法
- python 爬取作品集_Python批量抓取站酷ZCOOL作品图片并归档
- HIVE时间戳错误unix_timestamp时间不同环境相差8小时
- 1虚拟地址,虚拟内存映射,系统调用本质,进程运行状态
- 在Struts2中使用ValueStack、ActionContext、ServletContext、request、session等
- python求斐波那契数列第n个数及前n项和_使用python求斐波那契数列中第n个数的值示例代码...
- linux推出mysql对话_以及如何配置它以与Linux平台上的MySQL数据库对话
- jQuery.parseJSON()函数详解
- python测试开发django-8.windows系统安装mysql8教程