记一次MQ并发消费导致任务状态异常问题

背景:

项目中有一个短信群发任务(例如1次要发送1W条短信),系统会获取任务中每一条短信的MQ并发发送短信。任务默认状态是未发送(状态码:0),需要在这一批任务发送第一条短信的时候,将任务状态修改为发送中(状态码:1),在任务发送结束将状态修改为发送完成(状态码:2)。

代码处理逻辑:

伪代码如下,通过redis记录当前任务已发送了多少条,如果是第一条,则将任务状态更新为发送中,如果已发送条数等于任务总条数,将状态更新为发送完成

Long sendCount = redisTemplate.opsForValue().increment(taskId);
if(sendCount == 1){
   // 更新状态为发送中 update task set status = 1 where task_id = #{taskId}
}

if(sendCount >= totalCount){
  // 更新状态为发送完成 update task set status = 2 where task_id = #{taskId}
}

代码这么写,简单测试了两个任务,发现没有问题

问题:

实际线上运行的时候,发现部分任务始终是发送中状态,错误日志也没有异常,后来查日志才发现这种情况在并发比较高的时候会有问题,假设本次任务有2条短信,如下情况会导致任务一直处在发送中状态:

步骤第一条短信第二条短信任务状态
Long sendCount = redisTemplate.opsForValue().increment(taskId);执行未发送
Long sendCount = redisTemplate.opsForValue().increment(taskId);执行未发送
sendCount == 1false未发送
sendCount >= totalCounttrue发送完成
sendCount == 1true发送中
sendCount >= totalCountfalse不更新

即,第二条短信先判断if(sendCount >= totalCount)为true,将任务状态更改为发送完成,第一条短信再判断if(sendCount == 1)为true,将任务状态由发送完成变成发送中,但是第一条短信判断if(sendCount >= totalCount)为false,不会将任务状态变成发送完成,所以任务状态会一直是发送中

优化:

修改其实很简单,只需要将短信状态更新为发送中的时候,加一个判断,在任务状态不为2的时候才能更新。

Long sendCount = redisTemplate.opsForValue().increment(taskId);
if(sendCount == 1){
   // 更新状态为发送中 update task set status = 1 where task_id = #{taskId} and status <> 2
}

if(sendCount >= totalCount){
  // 更新状态为发送完成 update task set status = 2 where task_id = #{taskId}
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值