商城新客多领取优惠券问题

背景

年前开发的问题,总结一下:
用户在商城页面领取新客券,领过的用户不能再次领取,整个新用户领券逻辑如下:

Step 1: 验证商家是否登录、是否是老用户(R)
Step 2: 验证该商家是否领取过新客券(查询该商家拥有的优惠券是否含有新客券)(R)
Step 3: 领取新客券(W)
Step 4: 修改优惠券统计信息(W)
Step 5: 返回该商家刚刚领取的新客券(查询接口同Step 2)(R)

坑一:线上出现同一个用户领取多套优惠券情况,使用分布式锁解决

解决办法

增加分布式锁,使用 redis 缓存(锁未考虑当前线程),大致代码如下:

// @Transaction
Step 1: 验证商家是否登录、是否是老用户(R)
try{
  if(!lock.lock()) {
      return;
  }
  Step 2: 验证该商家是否领取过新客券(查询该商家拥有的优惠券是否含有新客券)(R)
  Step 3: 领取新客券(W)
  Step 4: 修改优惠券统计信息(W)
  Step 5: 返回该商家刚刚领取的新客券(查询接口同Step 2)(R)
} finally {
    lock.unlock();
}

坑二:加锁后仍然出现一个用户领取多套优惠券情况
在坑一出现问题的原因是多个线程并行时,很可能出现A线程释放B线程的锁,这里解决办法有多种,使用lua脚本使锁与线程相关 or 获取锁方法放到外面+超时时间 or threadLocal+锁改造,下面使用第二种:

解决办法

// @Transaction
Step 1: 验证商家是否登录、是否是老用户(R)
if(!lock.lock()) {  // 这里加上超时时间,否则若获取锁超时,很容易再次获取不到
    return;
}
try{
  Step 2: 验证该商家是否领取过新客券(查询该商家拥有的优惠券是否含有新客券)(R)
  Step 3: 领取新客券(W)
  Step 4: 修改优惠券统计信息(W)
  Step 5: 返回该商家刚刚领取的新客券(查询接口同Step 2)(R)
} finally {
    lock.unlock();
}

需要遵守:

lock.lock();
try{
   doSomething();
}finally{
   lock.unLock();
}

坑三:主从库延时可能导致用户领取新客券出现问题

解决办法

强制该事务中的SQL(包括读和写操作)都走主库

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

bboyzqh

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

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

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

打赏作者

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

抵扣说明:

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

余额充值