概述
很多业务场景下,有需要记录唯一性的需求,这个时候,业务代码的逻辑通常是先查询,存在则返回存在数据,不存在则插入数据。但是,在高并发场景下,多个线程进来,同时进行查询,此时都查询到没有记录,随后都进行插入,这样就会出现需要唯一约束的记录产生多条。虽然这种场景只会出现在记录不存在时且多个请求一起新增的情况下发生,概率虽小,根据墨菲定律,这种情况一定会发生。我们采取的策略也比较多,当前应用都是分布式服务,所以我们不考虑JVM锁的方式。
方案一
就是采取分布式锁,这种方案实现简单,但是对性能影响较大,因为99%情况都不需要去加这个锁的,只有在记录不存在的情况下,这把锁才是必须的,这种悲观的加锁方式很不划算。
这种方式还有一个改良版,就是先查询,如果不存在再去加分布式锁,这样的话,可以避免很多不需要加锁时加锁的操作。
方案二
就是添加唯一约束兜底,业务代码通过捕获唯一约束重复的异常进行处理,这种方式需要添加唯一约束,如果表设计中存在状态字段,唯一约束是某种状态的约束,那么添加主键的方式就不可行了。
方案三(不行)
就是写SQL时保证:
insert into xxx(a,b) select 'a1', 'b1' from dual
where not exists (select id from xxx where a=a1 and b=b1);
这种方式是比较简单的。业务代码可以通过判断返回值来做后续逻辑处理。事实证明这种写法是无法保证unique的。不要使用。
方案四
这种方案是限制接口在短时间内被多次调用,如果业务上能确定这个接口不可能在很短时间内以同一种参数被调用,那么完全应该限制起来,这是方案也不失为一种好的处理方式。缺点就是需要统筹设计接口重复调用拦截。
方案五
待补充
最后
以上就是怡然滑板为你收集整理的先查询后插入在高并发下重复插入问题解决方案一方案二方案三(不行)方案四方案五的全部内容,希望文章能够帮你解决先查询后插入在高并发下重复插入问题解决方案一方案二方案三(不行)方案四方案五所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复