并发情况下保持逻辑的顺序性

并发情况下保持逻辑的顺序性

  • 在日常开发中,经常会使用到异步消息去处理业务,今天说的场景是使用mq的方式去消费消息,但是如果同时过来多条消息,需要你在处理时候,保证顺序执行,比如更新商品,前后时间同时发过来两条消息,如果不加以判断,会把最后更新那一次的数据覆盖;或者是处理单据信息,相同的订单同时过来三种不同的状态,但是要求你需要按照顺序去执行,这时候该怎么做?在这里我根据实际的业务,提供三种不同的实现思路。
第一种,在发送消息之前,存入更新时间,消费时候,以最后一次更新的时间数据去消费;

参考代码如下:

  • 定义公共的实体字段,在每次发送消息之前,给操作时间operatorTime赋值,取当前时间;
  • 每次消费的时候,会把该字段存储在redis缓存中,当消息过来的话,会根据key去获取redis里边的时间,和传递过来的时间进行比较,如果传递过来的时候比缓存中的时间大,那么就执行;如果比缓存中的时间小,说明最后更新的先执行了,这次的无需操作,直接return就行
第二种,在发送消息之前,使用redis的hset方式,进行赋值,对于相同的订单,需要保证执行顺序;
  • hset(“no”,“1”,“1”);
  • hset(“no”,“2”,“2”);
  • 比如保证从小到大执行,那么消费的时候,根据key从redis中获取到数据后,进行排序,然后取第一个数值,get(0),和当前传递的值(1或者2)进行比较,如果比redis中取出的第一条大,那么就抛异常,进行重试;如果等于,那么就执行,完成之后,删除该条缓存信息,可以让后续的操作继续执行;
第三种,对第二种的变相,这种情况适合,生产者的数据信息是外部系统,不是你可以进行修改的;
  • 消费的时候,根据单号直接使用redis的分布式锁hSetNx来处理,如果第一次过来,根据单号去查询数据的单据状态,和传递过来的状态进行比较,如果不满足顺序条件的话,就抛出异常返回重试,finally删除缓存;如果满足条件的话,处理业务,更新状态,最后删除缓存,接下来继续消费该单号发送过来的其他状态的信息数据,按照这个处理方式进行消费,因为异常可以重试,直到都消费成功;
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值