高并发场景下数据重复插入的问题以及DuplicateKeyException异常在高并发下或批量插入数据时如何优化

问题:

       1.高并发时,数据库插入操作抛出DuplicateKeyException异常;

       2.批量插入数据的时,数据库插入操作抛出DuplicateKeyException异常;

异常信息如下:

      org.springframework.dao.DuplicateKeyException: ....(具体信息省略......)


解决方案:

 

      方案一:捕获异常,适用于需要对异常处理的程序,如交易订单号重复,给客户友好提示;

        try{
            // 入库操作
            inset into ...
        }catch (DuplicateKeyException e){
            // 返回响应信息或或略
        }

     方案二:数据库层面上进行忽略,这样遇到重复值就会跳过,后面的数据任然可以插入,适用于对单条数据的操作要求不严                       格,如批量处理数据;

1.insert ignore into ...
当插入数据时,如出现错误时,如重复数据,将不返回错误,只以警告形式返回。
所以使用ignore请确保语句本身没有问题,否则也会被忽略掉。
例如: 
INSERT IGNORE INTO table (XXX) VALUES ('xxx') 
这种方法很简便,但是有一种可能,就是加入不是因为重复数据报错,而是因为其他原因报错的,也同样被忽略了。

2.on duplicate key update 
当primary或者unique重复时,则执行update语句,如update后为无用语句,如id=id,则同1功能相同,但错误不会被忽略掉。
例如: 
INSERT INTO table (XXX) VALUES ('xxx') ON duplicate KEY UPDATE id = id 
这种方法的前提条件,就是,需要插入的约束,需要是主键(primary key)或者唯一约束(unique key)。

3.insert … select … where not exist 
根据select的条件判断是否插入,可以不光通过primary key 和unique来判断,也可通过其它条件。
例如: 
INSERT INTO table (XXX) SELECT 'xxx' FROM dual WHERE NOT EXISTS (SELECT id FROM table WHERE id = 1) 
这种方法其实就是使用了mysql的一个临时表的方式,但是里面使用到了子查询,效率也会有一点点影响,不是很推荐级。

4.replace into 
如果存在primary key or unique相同的记录,则先删除掉。再插入新记录。
例如: 
REPLACE INTO table SELECT 1, 'xxx' FROM table 
这种方法就是不管原来有没有相同的记录,都会先删除掉然后再插入。

      方案三:在对数据操作之前,先去数据库查重,然后对数据操作加锁或休眠线程等待,例如:redis 或线程sleep;不推荐,                         浪费系统性能,降低了系统的效率;

            
原因:

        mysql在批量插入数据的时候,如果有一个字段具有unique约束或是primary key ,而插入数据重复的话,就会抛出DuplicateKeyException,导致后续批量数据无法插入;

相关知识点:

      1.异常处理;

      2.数据库操作语句;

      3.锁机制;


代码示例:

     如上。
 

  • 2
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值