灵活运用分布式锁解决数据重复插入问题

本文探讨了在互联网业务中,由于并发请求导致的数据库数据重复问题。通过分析业务背景,发现问题是由于并发请求并发插入数据引起的。文章提出了两种解决方案:数据库层面的唯一索引和应用程序层面的分布式锁。最终,选择了使用分布式锁,特别是基于Redis的实现,以避免数据冲突。文章详细介绍了分布式锁的概念、特性、实现方式,包括基于数据库、Zookeeper和Redis的方法,并展示了基于Redis的Java实现。总结了在解决并发冲突时,如何权衡和选择合适的解决方案。
摘要由CSDN通过智能技术生成

一、业务背景

许多面向用户的互联网业务都会在系统后端维护一份用户数据,快应用中心业务也同样做了这件事。快应用中心允许用户对快应用进行收藏,并在服务端记录了用户的收藏列表,通过用户账号标识OpenID来关联收藏的快应用包名。

为了使用户在快应用中心的收藏列表能够与快应用Menubar的收藏状态打通,我们同时也记录了用户账号标识OpenID与客户端本地标识local_identifier的绑定关系。因为快应用Manubar由快应用引擎持有,独立于快应用中心外,无法通过账号体系获取到用户账号标识,只能获取到客户端本地标识local_identifier,所以我们只能通过二者的映射关系来保持状态同步。

在具体实现上,我们是在用户启动快应用中心的时候触发一次同步操作,由客户端将OpenID和客户端本地标识提交到服务端进行绑定。服务端的绑定逻辑是:判断OpenID是否已经存在,如果不存在则插入数据库,否则更新对应数据行的local_identifier字段(因为用户可能先后在两个不同的手机上登录同一个vivo账号)。在后续的业务流程中,我们就可以根据OpenID查询对应的local_identifier,反之亦可。 

 

但是代码上线一段时间后,我们发现t_account数据表中居然存在许多重复的OpenID记录。根据如上所述的绑定逻辑,这种情况理论上是不应该发生的。所幸这些重复数据并没有对更新和查询的场景造成影响,因为在查询的SQL中我们加入了LIMIT 1的限制,因此针对一个OpenID的更新和查询操作实际上都只作用于ID最小的那条记录。

二、问题分析与定位

虽然冗余数据没有对实际业务造成影响,但是这种明显的数据问题也肯定是不能容忍的。因此我们开始着手排查问题。

首先想到的就是从数据本身入手。先通过对t_account表数据进行粗略观察,发现大约有3%的OpenID会存在重复的情况。也就是说重复插入的情况是偶现的,大多数请求的处理都是按照预期被正确处理了。我们对代码重新进行了走读,确认了代码在实现上确实不存在什么明显的逻辑错误。

我们进一步对数据进行细致观察。我们挑选了几个出现重复情况的OpenID,将相关的数据记录查询出来,发现这些OpenID重复的次数也不尽相同,有的只重复一次,有的则更多。但是,这时候我们发现了一个更有价值的信息——这些相同OpenID的数据行的创建时间都是完全相同的,而且自增ID是连续的。

 

于是,我们猜测问题的产生应该是由于并发请求造成的!我们模拟了客户端对接口的并发调用,确实出现了重复插入数据的现象,进一步证实了这个猜测的合理性。但是,明明客户端的逻辑是每个用户在启动的时候进行一次同步,为什么会出现同一个OpenID并发请求呢?

事实上,代码的实际运行并不如我们想象中的那么理想,计算机的运行过程中往往存在一些不稳定的因素,比如网络环境、服务器的负载情况。而这些不稳定因素就可能导致客户端发送请求失败,这里的“失败”可能并不意味着真正的失败,而是可能整个请求时间过长,超过了客户端设定的超时时间,从而被人为地判定为失败,于是通过重试机制再次发送请求。那么最终就可能导致同样的请求被提交了多次,而且这些请求也许在中间某个环节被阻塞了(比如当服务器的处理线程负载过大,来不及处理请求,请求进入了缓冲队列),当阻塞缓解后这几个请求就可能在很短的时间内被并

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

倾听铃的声

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值