并发入库面临重复数据的问题

Posted 爱吃火龙果

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了并发入库面临重复数据的问题相关的知识,希望对你有一定的参考价值。

并发入库面临重复数据的问题

以User类为例,当添加一个用户时,首先会去判断用户是否已经存在(即username是否已经在数据库中了),如果没有,则insert一条用户数据,如果有,则提示用户名已存在。

将这个操作看作函数:UserService.saveUser(User user),有3个步骤:

private int saveUser(User user) {
  if
(1.username不存在) {     // 2.入库;   } else {     // 3.提示用户名已存在;   }
}

这个saveUser函数实际上是线程不安全的,假设两个线程A和线程B,两个线程同时进行了判断(步骤1),发现username不存在,那么就会导致user表中插入了两个username一样的数据(步骤2)。

解决方案一

最直接的,通过添加synchronized关键字,将方法变成同步方法

优点:简单直接

缺点:性能问题;后期的维护成本较高;最终要的,当服务部署在多台设备时不起作用


 解决方案二

在数据库的user表中,将username字段设为唯一索引,这样当插入重复数据时,数据库会抛出异常,无法入库,可以通过异常处理的方式来处理

优点:从比较根源的数据库层面解决了问题,适用与分布式环境

缺点:需要关注异常处理

 

以上是关于并发入库面临重复数据的问题的主要内容,如果未能解决你的问题,请参考以下文章

Java 多线程并发运用:解析单个大文件入库

在OOP代码中导入库的正确位置在哪里[重复]

转载:高并发简单解决方案 | 靠谱崔小拽 redis队列缓存 + mysql 批量入库 + php离线整合

Swift新async/await并发中利用Task防止指定代码片段执行的数据竞争(Data Race)问题

Swift新async/await并发中利用Task防止指定代码片段执行的数据竞争(Data Race)问题

高并发简单解决方案————redis队列缓存+mysql 批量入库