起因
最近的一次开发中,请求过来要判断数据是否存在,不存在则入库。由于是循环有着相同的数据入库请求,在执行时上一次事务还未提交,第二次的请求在数据库查询判断时发现数据不存在,又执行了一次入库请求,导致数据重复插入。以下列出了几种处理这种问题的思路,以后完善具体方案
使用消息队列
以kafka为例,可以在controller层不进行入库操作,将处理好的数据封装成对象发送一条kafka消息。再定义一个消费者去执行,由于消费者是有序执行。不会出现类似事务提交问题。
redis锁 / 内存缓存
执行插入操作时,向redis塞一条数据,等下次请求进来时,判断redis是否有相同数据,有的话则不进行插入操作。内存缓存同理。
数据库设置唯一键
在数据库对于相同数据的特征字段设置unique key,同时在代码里面捕获这个异常但不处理。这样重复数据不会插入,并且不会影响代码执行。这个方法有一定的局限性,数据库的唯一键限制了长度。在我的需求里面不适合使用。
方法加锁(synchronized)
影响效率,不推荐。无并发场景可以使用。
insert … where …
简而言之就是在数据入库的时候,通过sql判断当条数据是否存在,可以取某些特征字段 如name之类的,置于where 后面去判断