JAVA RedissonClient之自动取消订单

1.pom.xml文件中引入jar包

<dependency>
    <groupId>org.redisson</groupId>
    <artifactId>redisson-spring-boot-starter</artifactId>
    <version>3.16.4</version>
</dependency>

2.添加 RedissionClient的Bean对象

@Autowired
private RedissonClient redissonClient;

3.消息侦听器的使用

        a.获取消息发布订阅监听对象rTopic

        b.rTopic添加监听事件  String.class为消息类型  onMessage就是延迟处理的方法

        c.获取对象持有者RBucket (桶的概念) 

        d.为桶设置订单编号(id),生存时间(5)和时间单位(TimeUnit.SECONDS 秒)

        e.在订单结束后调用此方法 传入订单id

    /**
     * 新订单来了 设置订单自动取消
     * @param id 订单id
     */
    public void orderCancel(String id) {
        RTopic rTopic = redissonClient.getTopic("__keyevent@" + 1 + "__:expired", new StringCodec());
        rTopic.addListener(String.class, new MessageListener<String>() {
            @Override
            public void onMessage(CharSequence channel, String msg) {
                OrderServeCombo orderServeCombo = orderServeComboService.getById(id);
                if (ObjectUtils.isEmpty(orderServeCombo)) {
                    log.error("订单不存在,订单编号:{0}", id);
                }
                orderServeCombo.setStatus(OrderStatus.CANCEL);
                orderServeComboService.saveOrUpdate(orderServeCombo);
            }
        });
        RBucket bucket = redissonClient.getBucket("order");
        bucket.set(id, 5, TimeUnit.SECONDS);
    }

4.自动取消订单中,若服务器挂掉,上面方法不会执行 

是对orderCancel的补充(产生原因:订单即将到期 服务器挂了 即将取消的订单 未做处理)
/**
     * 处理未付款已过期 状态未取消的订单 是对orderCancel的补充(产生原因:订单即将到期 服务器挂了 即将取消的订单 未做处理)
     */
    private synchronized void dealCancelOrder(){
        Date now=new DateTime();
        Date cancelDate = DateUtils.addMinutes(now, -1);
        List<OrderServeCombo> list= orderServeComboService.list(Wrappers.<OrderServeCombo>lambdaQuery()
                .eq(OrderServeCombo::getStatus,OrderStatus.OBLIGATION)
                .le(OrderServeCombo::getCreateTime,cancelDate)
        );
        List<LambdaUpdateWrapper<OrderServeCombo>> wrapperList=new ArrayList<>();
        list.forEach(e->{
            e.setStatus(OrderStatus.CANCEL);
            e.setTimeoutTime(DateUtils.addMinutes(e.getCreateTime(),1));
            e.setUpdateTime(now);
        });
        orderServeComboService.updateBatchById(list);
    }

5.所以要在服务器启动的时候,自动执行方法处理订单已经取消,状态未刷新的订单

@PostConstruct注解被用来修饰一个非静态的void()方法。被@PostConstruct修饰的方法会在服务器加载Servlet的时候运行,并且只会被服务器执行一次。PostConstruct在构造函数之后执行,init()方法之前执行(返回必须是void)。

执行顺序:Constructor(构造方法) -> @Autowired(依赖注入) -> @PostConstruct(注释的方法)

   @PostConstruct
    public void init() {
        ThreadPoolExecutor threadPoolExecutor =
                new ThreadPoolExecutor(
                        1,
                        2,
                        5,
                        TimeUnit.MILLISECONDS,
                        new SynchronousQueue<Runnable>(),
                        Executors.defaultThreadFactory(),
                        new ThreadPoolExecutor.AbortPolicy());
        threadPoolExecutor.execute(new Runnable() {
            @Override
            public void run() {
                /**
                 * 处理 取消订单
                 */
                dealCancelOrder();
            }
        });
    }

6.也有可能服务器正常运行redis就是没执行订单过期的方法,如:(3.消息侦听器的使用)中未执行

所以在补充一条:每天一个时间点定时刷新 处理超时未付款订单

/**
 * 每天1点 处理一下超时未付款订单
 */
@Scheduled(cron = "0 0 1 * * ?")
private void autoDealCancelOrder(){
    dealCancelOrder();
}

最后完美解决。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值