【分布式锁】并发场景下的数据插入

并发场景下的数据插入

假设有这样一种场景,B为A做商品推销,A需要给B提供佣金,每推销成功一笔就要记录一笔佣金,假设每次记录的流水号为requestId,显然,每次推销成功一笔只能记录一次佣金,不然就会造成重复记录,给A造成经济损失。根据业务需求,可知requestId必然唯一。但是如果多个操作员同时为B记录佣金,就可能发生重复记录的问题,如何规避呢?

分析

假设有Tom和Jerry两个操作员,如果他们在同一台服务器上记录,显然可以通过加synchronized锁来规避重复计佣的风险。但是如果在不同的服务器上操作,我们都知道,synchronized是对象锁,不同的服务器必然是不同的对象,这时肯定失效。所以这里就需要引入分布式锁。

解决

  1. MySQL层
    首先分布式锁从底层的层面去分析的话,将requestId设置为唯一索引是可行的,但是需要注意两点:1)此时代码中需要显式的抛出DuplicateKeyException异常,否则如果重复插入会报异常,我们想要做的只是重复插入不去记录,并不想报错。2)唯一索引维护比较麻烦,删除的话一般选择物理删除,只是逻辑删除可能对未来业务扩展带来影响。
  2. 但是一般高并发场景都是尽量将请求拦截在最上游,这里可以通过ZK做分布式锁,也可以通过Redis锁,这里单介绍Redis。Redis的分布式锁比较简单,就是setnx()方法,即set if not exists,只会在键不存在的时候才会插入操作,而且Redis基于内存,响应很快,对于Tom和Jerry两个请求,必然只有其中一个请求到锁,执行插入操作。但是Redis往往是基于高并发(类似于一秒几千到上万个请求)的情况,正常操作用唯一索引就好。
  3. Zookeeper待补充。
    欢迎各位有志之士共同学习进步。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值