网站服务器租用需要注意的点,餐饮外哪个网站做推广,菏泽网站开发公司,自己可以做微网站吗先说一下事情产生的背景#xff1a;原先的代码逻辑是消费MQ#xff0c;然后请求其他服务的接口#xff0c;对接口的返回值result做落库操作#xff0c;现在要新加个逻辑#xff0c;做完落库操作后还要再将result封装落到新表中#xff1b;即消费一次MQ(MQ消息的频率非常高…先说一下事情产生的背景原先的代码逻辑是消费MQ然后请求其他服务的接口对接口的返回值result做落库操作现在要新加个逻辑做完落库操作后还要再将result封装落到新表中即消费一次MQ(MQ消息的频率非常高)两个落库操作(一个是新表)但上线时发现mysql连接被打满了然后通过自己公司的监控系统去排查原先的落库操作A的QPS只有800左右但新加的落库操作B却达到了4000的QPS直接翻了5倍当时就懵了看代码也没问题代码伪逻辑如下
1.获取MQ数据
2.用MQ数据去请求其他服务接口获取返回值
3.对返回值操作落到原先的表
4.对返回值封装落到新表中但问题就出现在这里了因为落新表时不只是直接insert4.1: 先根据封装后的值查询一次代码,如果数据库已有数据就update4.2: 如果数据库没有数据,就insertif(queryByTeaId(查询字段teacherId) !null){updateByTeaId(封装后的值和更新条件teacherId)}else{insert(封装后的值) }结果由于新表对于查询字段没有建立索引且虽然是新表但另一个离线任务一直在往里写着数据已有的数据量已经非常大了 导致报错com.alibaba.druid.pool.GetConnectionTimeoutException后来对表中字段teacherId加了唯一索引后完美解决问题。
但后续又延伸出另一个问题Mysql表中teacherId是设置的唯一索引但由于是一直消费MQMQ消息中是studentId会反查teacherId所以多个消息可能对应的是同一个teacherId但代码都懂得多线程执行的所以插入时偶然在代码中报了唯一键重复的错误由于文章时后面写的具体报错没保存也懒的百度了虽然是偶发事件但还是得解决本来想的是在代码中把查询、插入、更新的代码写带一个方法中给这个方法加上Transactional事务注解但后来一想多线程情况下这也解决不了问题但此业务又不是很重要没必要用到分布式锁所以后面从sql入手使用ON DUPLICATE KEY UPDATE算是解决了多线程插入导致唯一键冲突的问题如下
-- teacher_id 设置的是唯一索引
insert into tableName name,age,sex,teacher_id values(zhangsan,18,1,1234) ON DUPLICATE KEY UPDATE name lisi,
age 19,sex 0 ;
由于很少用ON DUPLICATE KEY UPDATE所以我以为只会检查主键是否重复特意去百度了下介绍如下
ON DUPLICATE key update是根据索引字段是否重复来判断是否执行如果重复则执行update否则则执行insert。
优先级主键唯一索引当主键重复时则执行update当主键不重复唯一索引重复时也执行update当主键和唯一索引值都不重复才执行insert
特殊情况当主键重复执行update时如果此时唯一索引字段与其他字段也重复则会报错