背景
1.从rabbitMq拉取数据消费,并发数10,10个线程同时执行一段代码逻辑(如下)
// 逻辑先查询,有数据更新,无数据插入
// 逻辑1
Object obj = xxxMapper.selectBySelective(Object parame);
if(obj !=null){
// 逻辑2
xxxMapper.updateBySelective(Object parame);
}else{
// 逻辑3
xxxMapper.insert(Object parame);
}
问题开始
1.逻辑1出现查询到多条数据,报错了.仔细一看代码报错了,此处代码存在多线程问题
解决方案有
1.JVM锁,synchronized,保证次块代码只有一个线程访问(集群部署没辙)
synchronized(this){
// 逻辑1
Object obj = xxxMapper.selectBySelective(Object parame);
if(obj !=null){
// 逻辑2
xxxMapper.updateBySelective(Object parame);
}else{
// 逻辑3
xxxMapper.insert(Object parame);
}
}
2.分布式锁搞起, redisson,(有人觉得分布式锁耗性能,因为需要获取锁,释放锁)
3.sql解决方案,将压力完全放在了数据库.(insert的时候会因为数据增多导致后面的查询有所变慢)
并发非常高的情况会导致死锁
INSERT INTO 表名
(字段1,字段2) SELECT 值1,值2 FROM DUAL
WHERE NOT EXISTS (
SELECT id FROM 表名 WHERE 字段1 = 值1 and 字段2= 值2
) ;
// 先查询,有数据走update, 没数据走上面的插入,插入失败走更新
// 这样无需分布式锁可解决并发问题