查询并更新 在多线程 中出现问题

2020-01-03  本文已影响0人  anyly
背景

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,  没数据走上面的插入,插入失败走更新
// 这样无需分布式锁可解决并发问题
解释:不是不想用分布式锁,其他原因导致.
上一篇下一篇

猜你喜欢

热点阅读