Java并发添加数据,如何保证不会添入相同的数据?

我有这样的业务场景:

一个接口往mysql的user表中insert数据,一个realname字段和一个groupid字段。

我现在想保证realname添入的时候同一group下不能有重复的,但是我现在不能给这两个字段加联合唯一索引。

因为库里realname有很多是空的情况。

问题:

现在我在用大量线程访问这个接口,添加user。这些线程realname如果有相同的,就可能会添入realname一样的数据。

我如何处理才能保证一定不会添入重复数据?不能用synchronized关键字,因为是多机集群部署。

一个服务器保证同步,其他的依然肯定会出现这个问题。

小弟请教各位大神,这种情况如何处理,小弟技术小白一个,请详细一点说明,先谢谢各位了。

4个回答

每次插入,写个额外线程去查重,如果有重复则删除只剩一个

如果不可以重复的是一个字段的话 可以设为主键 如果不是一个的话只能在insert前检测

这种情况的话,你可以借助于消息队列,比如rabbitmq,或redis的list,即你把你的所有线程的操作不要直接插入数据库,而是先放到消息队列中,再另起一个服务,从消息队列中接收数据并存储。在这个服务上再加一层缓存,把插入过的数据都缓存起来,插入的时候从缓存中查看是否已经存在了。
这样你的业务也不用再等数据库返回了。可以增加处理效率。

u013259496
墓地的夜空 貌似,没有考虑到以存在于数据库里面的数据的匹对;
接近 4 年之前 回复

在服务启动的时候,要把数据库中已存在的数据加载到缓存中,如果数据量大,可以使用带持久化的缓存,比如redis。

Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
其他相关推荐
Python+OpenCV计算机视觉

Python+OpenCV计算机视觉

Java并发编程之美 、 Java并发编程的艺术 、实战Java高并发程序设计 这三本书哪本好一点

Java并发编程之美 、Java并发编程的艺术 、 实战Java高并发程序设计 这三本书哪本好一点 感觉都差不多 哪本适合找实习的大学生

[并发]判断条件同时插入数据

业务逻辑: 两个老师在同一或交叉时间段内在同一教室开课,只能有一个老师开课成功, 虽然在插入开课数据前,做了代码层面的判断,但通过压测,仍不能有效避免并发开课成功的结果,请问各位有没有一种有效的解决方案? ``` //判断教室是否占用 if (class_update_status == 1) { boolean canUse = classroomCanUse(class_id, startInputDate, endInputDate); //教室不可用 if (!canUse) { return ResultBean.setOk(1, "添加课时失败,该时间段此教室已被占用,请预约其他教室"); } } int i = lessonPeriodMapper.insertPeriod(period); //添加直播课时成功 if (i > 0) { int new_period_id = period.getPeriod_id(); int seconds=(int)((endTime- System.currentTimeMillis())/1000); redisUtils.setex(new_period_id + "_ossurl",seconds,oss_path); map.put("period_id", new_period_id); updateProgressPriodNumber(lesson_id); return ResultBean.setOk(0, "添加直播课时成功", map); } ``` ![图片说明](https://img-ask.csdn.net/upload/201910/23/1571798878_610645.png) 开启100个并发线程 当执行延迟为1s时候并不会出现并发插入多条成功的情况,延迟为0s时候最多出现并发插入成功5条,实际场景虽然出现延迟0s的几率很少,但仍不能根本解决问题.

高并发情况下怎么避免数据重复

数据库有一字段:orderNo,orderNo的规则:20170327000001、20170327000002依次往后累加。。。并发时怎么避免存入重复的

java关于并发查询数据库的问题

java关于并发查询数据库的问题 问题如下 1,从数据库查询2条数据 2,循环2条数据请求第三方接口(耗时)(每条数据只能请求3次第三方接口) 3,请求成功则修改该条数据(请求第三方的次数+1)。 现在的问题是 并发情况下,两个线程同时进来,取到2条数据(已经请求过第三方接口两次) 这时候两个线程同时再去请求第三方接口,得到的结果就只会有一个成功。因为另一个已经达到3次了。 这种问题应该怎么解决???

怎么处理数据并发问题

在java中怎么处理数据并发的问题,用是技术框架比较合适求指点。

关于java并发编程,完整代码

谁能给个完整的 、有关java 并发编程的例子?多个客户端向服务器传输数据

多并发获取不到最新数据

在springboot项目中,并发一秒5单进入异步方法, 5单获得相同的50条数据, ![图片说明](https://img-ask.csdn.net/upload/201901/24/1548323169_550637.png) 第1单操作锁定50条中的订单A,读取并修改, 同时第2,3,4单发现订单A被锁住了会依此操作订单B,C,D 这时订单A执行完成并解锁, 如果第5单进入了解锁后的第1单操作过的订单A, 查询订单A得到的数据是第1单没修改之前的而不是修改之后的,是为什么呢? ![图片说明](https://img-ask.csdn.net/upload/201901/24/1548323261_313622.png)

多用户高并发插入数据怎么解决并发问题

场景: 类似银行存取,增减账户余额,但是多了明细表,每次转账更新用户同一条数据记录,但是用户明细表一直递增信息记录,关键字段为当前余额(操作金额加上原余额得出) 问题: 更新同一条记录可以通过增加version字段解决高并发同时写的问题 但是明细表中先读取原先余额再写入新余额,这个怎么解决,怎么能让每次读出余额是最新的,写入明细之前余额不会被修改

java事务下并发问题怎么搞

现在业务中在实现类serviceImpl.aaaa()方法(事务在该方法上)中有相关业务 业务大概就是 查库中字段sta='R'的数据--》处理逻辑--》修改数据将字段sta改为='I' 现在出现得问题就是多个线程进入后 多个线程同时去请求,**在查数据过程中由于并发获取到了同样的数据** 然后再通过同样逻辑后 去update数据是就发生了相互覆盖得情况,后执行得把前面执行的给了覆盖了,最终相当于数据中只有一条修改语句而不是多条。 各位这种要怎么解决。

高并发情况下的数据如何存储最节省空间

考虑 用户基数 1亿,日活用户 1kw的 一个APP系统,如果要开发签到功能,要求支持大并发,如何存储签到数据最节省空间?1个月后 需要多少空间存储这些数据? 用户id是Long型数据,均匀分布在 0-400000000之间,日活用户30%签到,使用哪些命令存储签到数据, 获取 某用户的某些天是否签到 使用什么命令?

java的阻塞while如何避免并发量大时不掉数据呢

在做一个socket的小应用,在监听是否有数据输入时使用了while,其中有Thread.sleep(10),主要是为了防止cpu满负载。因为服务器是单CPU的,之前就出现了这个情况,如果直接while没有sleep的话,CPU很快就100%了。 如果我Socket socket = server.accept();包裹在一个while里,那是否在并发量多的时候,就一定会有一些连接丢失? while(!stop){ try { Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } String con = null; try { con = is.readUTF(); } catch (IOException e1) { e1.printStackTrace(); stop = true; } if(con!=null)putRevData(con);//putRevData是一个ArrayList,将收到的数据先存入队列里等待处理 } 这里的readUTF好像也是阻塞的,应该不会丢失。 但是如果是 while(true){ Thread.sleep(10); socket = server.accept(); if(socket != null){ //做处理。这里将开启新的线程,并将其放入一个HashMap中,等待其他连接进入 } } 如果是这样的话,那是否在并发多的时候,就会有sokcet接收不到了呢? 我自己做了一个测试,用for不断的输入数据,在阻塞接收中有很多数据就掉了。 如果放入数据的线程sleep大于接收数据的sleep,就能全接收到数据,但是一旦小于就会不通程度的丢失数据。 class TestSleep extends Thread{ private ArrayList<String> a = new ArrayList<String>(); String rev = null; boolean stop,start = false; public synchronized void push(){ this.a.add(rev); rev = null; } public void shut(){ this.stop = true; } public synchronized void put(String a){ this.rev = a; } public synchronized void setRevNull(){ this.rev = null; } public void show(){ System.out.println(a); } public boolean isStart(){ return this.start; } public void run(){ while(!stop){ if(!this.start) this.start = true; try { Thread.sleep(5); } catch (InterruptedException e) { // TODO 自动生成的 catch 块 e.printStackTrace(); } if(rev!=null){ push(); } } show(); } } class putA extends Thread{ TestSleep ts = null; String con = null; putA(TestSleep a){ this.ts = a; } void setStr(String a){ con = a; } public void run(){ ts.put(con); } } public class TempTest { public static void main(String[] args) throws JSONException, IOException, InterruptedException { TestSleep a = new TestSleep(); a.start(); Map<Integer,putA> map = new HashMap<Integer,putA>(); for(int i = 0;i<10;i++){ Thread.sleep(4); putA b = new putA(a); b.setStr("num"+i); map.put(i, b); b.start(); } System.out.println(map.size()); Iterator<Map.Entry<Integer, putA>> entries = map.entrySet().iterator(); while(map.size()!=0){ while(entries.hasNext()){ Map.Entry<Integer, putA> entry = entries.next(); if(!entry.getValue().isAlive())entries.remove(); } } a.shut(); } } 这是一个很矛盾的事情。因为while里必须得用一个sleep才能避免cpu负载的问题,但是如果一旦加了sleep,在并发量大的时候一定会有数据掉的。 想到了可以用java.nio的包来监听。但是好像Nio的包也只是对传统阻塞io做了另一个封装而已,那实现原理呢? 请大神指点一下。

java并发问题(SSH相关)

问一:多个客户端访问同一个带有字段的类,会不会有触发到线程安全的问题 问二:多个客户端访问同一个代码块,都会有自己的堆栈吗? 问三:Struts中单例和多例是不是为了解决线程安全的问题。才会有多例 ,为每个客户端都创建一个实例

java并发访问一个变量问题

``` public class Test2 { public static int count = 0; public static void main(String[] args) { new Thread(new Runnable() { @Override public void run() { while(count<=20){ System.out.println(Thread.currentThread().getName()+":"+count); count++; } } }).start(); new Thread(new Runnable() { @Override public void run() { while(count<=20){ System.out.println(Thread.currentThread().getName()+":"+count); count++; } } }).start(); } } ``` 输出:Thread-0:0 Thread-0:1 Thread-0:2 Thread-0:3 Thread-0:4 Thread-0:5 Thread-0:6 Thread-1:6 Thread-1:8 Thread-1:9 Thread-0:7 Thread-1:10 Thread-0:11 Thread-1:12 Thread-0:13 Thread-1:14 Thread-0:15 Thread-1:16 Thread-0:17 Thread-1:18 Thread-1:20 Thread-0:19 当线程一输出9的时候,线程0确输出了7. 我就不理解了,当线程1切换到线程0的时候,至少应该输出>=9才对

关于java多线程并发读写的问题

1.文件内容读取到缓存 2.从缓存获取文件内容,写入到磁盘 3.控制缓存大小 4.多线程并发写丶读

高并发下数据库中如何解决重复插入数据的问题

昨天面试,被面试官问到。。。 比如用户注册时,先要验证用户名是否存在,但是在验证过后可能还会被插入相同用户名的数据,这就造成了冲突。 应该怎么解决?

求 有关 高并发 数据区 读取更新 数据 的解决办法

问题:高并发 数据库取数据,每次取到一条数据后更新这条数据的状态为已取用过。 环境:3台服务器跑应用 处理请求,多线程数据库取数据 有点类似 12306的买票,查找过资料 有看到 1W人 同时抢一张票的问题。 现在考虑的问题是,如果票是足够多的,如何解决高并发取数据冲突的问题,如果用加锁的方式,会出现大量请求都取一条数据,导致 等待时间太长。 有没有 好的方案,可以避免同时请求到同一条数据。

【求助大佬】关于java并发实际操作中出现的一个问题

这是我的部分代码: if (bufferList.size() < 500) { bufferList.add(song); } else { synchronized (this) { try { // 为了性能,用SpringJDBC Date date = new Date(); batchInsertSelective(bufferList); Date date1 = new Date(); System.out.println("[INFO] 线程\t" + Thread.currentThread().getId() + "\t本次插入所花时间:\t" + (date1.getTime() - date.getTime())); bufferList.clear(); objectCount += bufferList.size(); } catch (Exception e) { e.printStackTrace(); logger.error(e.getMessage()); } } } 情景:多个线程访问这一段代码,如果缓存List大小大于500就调用batchInsertSelective将数据批量导入数据库,为了测试,我加上了两个时间用来测试insert的时间,并打印。因为加了锁,所以数据库并没有出现重复的问题。但打印的时候问题来了: [INFO] 线程 57 本次插入所花时间: 1106 [INFO] 线程 89 本次插入所花时间: 0 [INFO] 线程 36 本次插入所花时间: 0 [INFO] 线程 45 本次插入所花时间: 0 [INFO] 线程 76 本次插入所花时间: 0 [INFO] 线程 42 本次插入所花时间: 0 [INFO] 线程 58 本次插入所花时间: 0 [INFO] 线程 86 本次插入所花时间: 0 [INFO] 线程 67 本次插入所花时间: 0 [INFO] 线程 81 本次插入所花时间: 0 [INFO] 线程 64 本次插入所花时间: 0 [INFO] 线程 79 本次插入所花时间: 0 [INFO] 线程 71 本次插入所花时间: 0 [INFO] 线程 88 本次插入所花时间: 0 打印的时候会显示这样(数据库数据没有受到此问题的影响,没有重复值)。 求助大神解答一下。

在java中,需要关心数据库连接的并发情况吗?

因为做了数据库的连接类 最近在使用的时候倒是没有什么问题,但是个人考虑在访问增多以后,这样的数据库连接是否 需要考虑并发的问题?不然会出现异常。因为在个人测试的时候,如果在调用一个ft_con类 后,在调用过程中,如果在没有关闭之前,会碰到rs空指针的情况。 但是,是否没一个请求(session)都是单独的,在服务器端会生成一个ft_con的单独实例。所以 不会产生并发问题? 望大家给些指导,还请教一下,这样的写法有没有什么潜在问题?是否具有通用性呢? public ft_con(){ if(conn==null){ try{ //Class.forName("com.microsoft.sqlserver.jdbc"); 基本不使用。 //Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver"); //看是否引入数据包成功 Class.forName("com.mysql.jdbc.Driver"); } catch(Exception ex){ System.out.println(ex); } try{ conn = DriverManager.getConnection(url,user,password); //创建连接 } catch(Exception ex){ System.out.println("connection create false"); //连接不成功则输出 System.out.println(ex); } } } public Connection getConn(){ return conn; } public void Set_st(){ try{ st = conn.createStatement(); }catch(Exception ex){ System.out.println("无法创建statement"); System.out.println(ex); } } public ResultSet getRs(String sql){ try{ rs = st.executeQuery(sql); }catch(Exception ex){ ex.printStackTrace(); } return rs; } public int updata(String sql){ int num=0; try{ num = st.executeUpdate(sql); }catch(SQLException e){ e.printStackTrace(); } return num; } public void close(){ try{ if(rs!=null){ rs.close(); rs = null; } if(st!=null){ st.close(); st = null; } if(conn!=null){ conn.close(); conn = null; } }catch(SQLException e){ e.printStackTrace(); } }

java 并发处理耗时操作的问题

刚刚写了个测试程序 原本想使用多线程并发处理 来节省时间,结果反而更耗时。请各位指点一下。 主方法: public class MainAction { public static void main(String[] args) { /*new Action1().run(); new Action2().run(); new Action3().run();*/ new Thread(new Action1()).start(); new Thread(new Action2()).start(); new Thread(new Action3()).start(); } } Action1 /2/3(方法一样,只是文件大小不同): public class Action1 implements Runnable{ public void run() { System.out.println("start 1.........."); long start1 = System.currentTimeMillis(); writeToTxt("123"); Context.flg1 = 1; long end1 = System.currentTimeMillis(); float second1 = (end1 - start1) / 1000F; System.out.println("end 1 cost " + second1 + " s"); } public void writeToTxt(String text){ File file = new File("D:/1.txt"); FileWriter fw = null; BufferedWriter writer = null; try { fw = new FileWriter(file); writer = new BufferedWriter(fw); for (int i=0;i<200*1000*10;i++) { writer.write(text); writer.newLine();//换行 } writer.flush(); } catch (FileNotFoundException e) { e.printStackTrace(); }catch (IOException e) { e.printStackTrace(); }finally{ try { writer.close(); fw.close(); } catch (IOException e) { e.printStackTrace(); } } } } 运行结果: start 1.......... start 2.......... start 3.......... end 2 cost 89.906 s end 3 cost 115.905 s end 1 cost 163.817 s 如果使用上面注掉的串行 运行: start 1.......... end 1 cost 13.681 s start 2.......... end 2 cost 18.752 s start 3.......... end 3 cost 20.051 s 求解,是不是程序并没有真正的多线程去执行。 另外,如果Action1/2/3 是3个远程调用,能否达到节省时间的效果?

2019 Python开发者日-培训

2019 Python开发者日-培训

150讲轻松搞定Python网络爬虫

150讲轻松搞定Python网络爬虫

设计模式(JAVA语言实现)--20种设计模式附带源码

设计模式(JAVA语言实现)--20种设计模式附带源码

YOLOv3目标检测实战:训练自己的数据集

YOLOv3目标检测实战:训练自己的数据集

java后台+微信小程序 实现完整的点餐系统

java后台+微信小程序 实现完整的点餐系统

三个项目玩转深度学习(附1G源码)

三个项目玩转深度学习(附1G源码)

初级玩转Linux+Ubuntu(嵌入式开发基础课程)

初级玩转Linux+Ubuntu(嵌入式开发基础课程)

2019 AI开发者大会

2019 AI开发者大会

玩转Linux:常用命令实例指南

玩转Linux:常用命令实例指南

一学即懂的计算机视觉(第一季)

一学即懂的计算机视觉(第一季)

4小时玩转微信小程序——基础入门与微信支付实战

4小时玩转微信小程序——基础入门与微信支付实战

Git 实用技巧

Git 实用技巧

Python数据清洗实战入门

Python数据清洗实战入门

使用TensorFlow+keras快速构建图像分类模型

使用TensorFlow+keras快速构建图像分类模型

实用主义学Python(小白也容易上手的Python实用案例)

实用主义学Python(小白也容易上手的Python实用案例)

程序员的算法通关课:知己知彼(第一季)

程序员的算法通关课:知己知彼(第一季)

MySQL数据库从入门到实战应用

MySQL数据库从入门到实战应用

机器学习初学者必会的案例精讲

机器学习初学者必会的案例精讲

手把手实现Java图书管理系统(附源码)

手把手实现Java图书管理系统(附源码)

极简JAVA学习营第四期(报名以后加助教微信:eduxy-1)

极简JAVA学习营第四期(报名以后加助教微信:eduxy-1)

.net core快速开发框架

.net core快速开发框架

玩转Python-Python3基础入门

玩转Python-Python3基础入门

Python数据挖掘简易入门

Python数据挖掘简易入门

微信公众平台开发入门

微信公众平台开发入门

程序员的兼职技能课

程序员的兼职技能课

Windows版YOLOv4目标检测实战:训练自己的数据集

Windows版YOLOv4目标检测实战:训练自己的数据集

HoloLens2开发入门教程

HoloLens2开发入门教程

微信小程序开发实战

微信小程序开发实战

Java8零基础入门视频教程

Java8零基础入门视频教程

相关热词 c#跨线程停止timer c#批量写入sql数据库 c# 自动安装浏览器 c#语言基础考试题 c# 偏移量打印是什么 c# 绘制曲线图 c#框体中的退出函数 c# 按钮透明背景 c# idl 混编出错 c#在位置0处没有任何行
立即提问