一次高并发问题记录

一次高并发问题记录

###场景复述:

  • 目前做了一个Excel导入的功能:

    1. 先读取整个Excel,遍历读取到的List将数据库中已存在等无效数据的剔除

    2. 批量插入数据库

  • 问题复现:

  1. 连续两次导入同一份文件
  • 结果:
  1. 数据库中存在两份相同的数据
  • 原因分析:

​ 上次的导入还没执行完毕,这次又导入。每次查询数据库都显示库位不存在,所以插入了两遍。
目前现场只要等上次导入结果出来后,再导入就不会出现问题。

  • 解决方案:
  1. 最简单的方案是加锁,串行导入 – 但是本来导入速度就慢 加锁后性能就更是个问题,好在导入使用频率不高,并且这个解决方案最快速
  2. 在bathInsert的时候数据库使用INSERT IGNORE INTO(INSERT IGNORE INTO表示,如果中已经存在相同的记录,则忽略当前新数据) 但是这个东西需要一个唯一索引!也就是说我们要给线上数据库增加一个code字段的唯一索引!但是线上数据已经是脏数据了(一定存在编码code重复的数据,因为删除我采用的是软删除),所以执行新增唯一索引为时已晚!!!

关于唯一索引问题:

	想起阿里巴巴Java开发手册里一些内容:

##索引规约

  1. 【强制】业务上具有唯一特性的字段,即使是组合字段,也必须建成唯一索引。 说明:不要以为唯一索引影响了 insert 速度,这个速度损耗可以忽略,但 高查找速度是明 显的;另外,即使在应用层做了非常完善的校验控制,只要没有唯一索引,根据墨菲定律,必 然有脏数据产生。

    (墨菲定律:

    一、任何事都没有表面看起来那么简单;

    二、所有的事都会比你预计的时间长;

    三、会出错的事总会出错;

    四、如果你担心某种情况发生,那么它就更有可能发生。有唯一特性还不建立唯一索引真是浪费数据库的能力,数据库的唯一校验比代码准多了)

  2. 【参考】创建索引时避免有如下极端误解:

    • 误认为一个查询就需要建一个索引。(只要用到的索引能把数据查询范围缩小很多就可以了,比如说原来1000万数据,其中光item_id字段就能把范围降到100以内,那么查询条件里那些begin_time字段就不用一起建立组合索引了
    • 误认为索引会消耗空间、严重拖慢更新和新增速度。(难道不会拖慢吗?)
    • 误认为唯一索引一律需要在应用层通过“先查后插”方式解决

你可能感兴趣的:(Java语言)