基于Redis过期事件实现订单超时取消

订单超时取消的实现,首先想到的是定时任务,但是这种实现方式在订单量较大的情况下是有问题的,而且时间也会有误差,最大时间差就是定时任务的执行间隔时间。

使用redis的过期监听事件可以比较好的解决这个问题。实现的方式是订单创建后向redus中存一记录,一般就以订单号为key。设置过期时间(订单超时时间),一旦时间超时会触发监听事件,这时候就可以通过key判断这个订单是否支付,未支付时取消订单。

redis过期监听的实现:

1.修改redis.windows.conf配置文件中notify-keyspace-events的值

默认配置notify-keyspace-events的值为" ",修改为 notify-keyspace-events Ex 这样便开启了过期事件

2. 创建配置类RedisListenerConfig(配置RedisMessageListenerContainer这个Bean)

@Configuration
public class RedisListenerConfig {

    @Autowired
    private RedisTemplate redisTemplate;

    /**
     * 处理乱码
     * @return
     */
    @Bean
    public RedisTemplate redisTemplateInit() {
        // key序列化
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        //val实例化
        redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer());

        return redisTemplate;
    }

    @Bean
    RedisMessageListenerContainer container(RedisConnectionFactory connectionFactory) {

        RedisMessageListenerContainer container = new RedisMessageListenerContainer();
        container.setConnectionFactory(connectionFactory);
        return container;
    }

}

3.继承KeyExpirationEventMessageListener创建redis过期事件的监听类

KeyExpirationEventMessageListener类是org.springframework.data.redis.listener包下的实现类,通过继承这个类重写onMessage方法可以实现对redis所有过期事件的监听。

@Component
public class RedisKeyExpirationListener extends KeyExpirationEventMessageListener {
    public RedisKeyExpirationListener(RedisMessageListenerContainer container) {
        super(container);
    }

    /**
     * 针对redis数据失效事件,进行数据处理
     * @param message
     * @param pattern
     */
    @Override
    public void onMessage(Message message, byte[] pattern) {
       String key=message.toString();//生效的key
        if (key!=null && key.startsWith("order")){//从失效key中筛选代表订单失效的key
            //截取订单号,查询订单,如果是未支付状态则取消订单
            String orderNo=key.substring(5);
            System.out.println("订单号为:"+orderNo+"的订单超时未支付,取消订单");

        }
    }
}

测试

通过redis模拟创建一个有效时间为5s的订单:

5秒后程序成功监听到了过期事件:

到此这篇关于基于Redis过期事件实现订单超时取消的文章就介绍到这了,更多相关Redis 订单超时取消内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • 使用PHP+Redis实现延迟任务,实现自动取消订单功能

    简单定时任务解决方案:使用redis的keyspace notifications(键失效后通知事件) 需要注意此功能是在redis 2.8版本以后推出的,因此你服务器上的reids最少要是2.8版本以上: (A)业务场景: 1.当一个业务触发以后需要启动一个定时任务,在指定时间内再去执行一个任务(如自动取消订单,自动完成订单等功能) 2.redis的keyspace notifications 会在key失效后发送一个事件,监听此事件的的客户端就可以收到通知 (B)服务准备: 1.修改reid

  • Redis中的String类型及使用Redis解决订单秒杀超卖问题

    本系列将和大家分享Redis分布式缓存,本章主要简单介绍下Redis中的String类型,以及如何使用Redis解决订单秒杀超卖问题. Redis中5种数据结构之String类型:key-value的缓存,支持过期,value不超过512M. Redis是单线程的,比如SetAll & AppendToValue & GetValues & GetAndSetValue & IncrementValue & IncrementValueBy等等,这些看上去像是组合命

  • PHP实现电商订单自动确认收货redis队列

    一.场景 之前做的电商平台,用户在收到货之后,大部分都不会主动的点击确认收货,导致给商家结款的时候,商家各种投诉,于是就根据需求,要做一个订单在发货之后的x天自动确认收货.所谓的订单自动确认收货,就是在在特定的时间,执行一条update语句,改变订单的状态. 二.思路 最笨重的做法,通过linux后台定时任务,查询符合条件的订单,然后update.最理想情况下,如果每分钟都有需要update的订单,这种方式也还行.奈何平台太小,以及卖家发货时间大部分也是密集的,不会分散在24小时的每分钟.那么,

  • Redis实现订单自动过期功能的示例代码

    前言 用户下单后,规定XX分钟后自动设置为"已过期",不能再发起支付.项目类似此类"过期"的需求,笔者提供一种使用Redis的解决思路,结合Redis的订阅.发布和键空间通知机制(Keyspace Notifications)进行实现. 配置redis.confg notify-keyspace-events选项默认是不启用,改为notify-keyspace-events "Ex".重启生效,索引位i的库,每当有过期的元素被删除时,向**key

  • 基于Redis过期事件实现订单超时取消

    订单超时取消的实现,首先想到的是定时任务,但是这种实现方式在订单量较大的情况下是有问题的,而且时间也会有误差,最大时间差就是定时任务的执行间隔时间. 使用redis的过期监听事件可以比较好的解决这个问题.实现的方式是订单创建后向redus中存一记录,一般就以订单号为key.设置过期时间(订单超时时间),一旦时间超时会触发监听事件,这时候就可以通过key判断这个订单是否支付,未支付时取消订单. redis过期监听的实现: 1.修改redis.windows.conf配置文件中notify-keys

  • python使用celery实现订单超时取消

    本文实例为大家分享了celery实现订单超时取消的具体代码,供大家参考,具体内容如下 Celery官方文档中关于定时任务使用的说明 项目目录结构 我们需要新增一个任务目录,例如order: celey_tasks/      ├── config.py      ├── __init__.py      ├── main.py      ├── order/             ├── __init__.py            └── tasks.py 在main.py中,注册任务目录[

  • Java实现商城订单超时取消功能

    大多数的B2C商城项目都会有限时活动,当用户下单后都会有支付超时时间,当订单超时后订单的状态就会自动变成已取消 ,这个功能的实现有很多种方法,本文的实现方法适合大多数比较小的商城使用. 实现原理: 利用 jdk 的 DelayQueue的阻塞队列的特性实现.在项目启动时开启一个线程处理 DelayQueue 队列里弹出的超时订单对象,订单未超时该线程处于等待中. DelayQueue的简单介绍: DelayQueue类的主要作用:是一个无界的BlockingQueue,用于放置实现了Delaye

  • springboot+redis过期事件监听实现过程解析

    1 修改 redis.conf配置文件: K Keyspace events, published with keyspace@ prefix事件 E Keyevent events, published with keyevent@ prefix g Generic commands (non-type specific) like DEL, EXPIRE, RENAME, - $ String commands l List commands s Set commands h Hash co

  • Java实现订单超时未支付自动取消的8种方法总结

    目录 定时轮询 惰性取消 JDK延迟队列 时间轮 Redis过期回调 Redis有序集合 任务调度 消息队列 定时轮询 数据库定时轮询方式,实现思路比较简单.启动一个定时任务,每隔一定时间扫描订单表,查询到超时订单就取消. 优点:实现简单. 缺点:轮询时间间隔不好确定,占用服务器资源,影响数据库性能. 惰性取消 当查询订单信息时,先判断该订单是否超时,如果超时就先取消. 优点:实现简单. 缺点:影响查询之外的业务(如:统计.库存),影响查询效率. JDK延迟队列 JDK延时队列DelayQueu

  • redis监听key过期事件的详细步骤

    目录 1.配置redis.conf文件 2. 配置一个key过期事件的监听器 3.订阅key过期事件 4.发起订阅 1.配置redis.conf文件 配置文件默认是#注释了的,改为notify-keyspace-events Ex    重启redis,记住指定redis.conf配置文件启动 如果是阿里云的redis,进入redis管理页面==>>左边导航栏的参数设置 2. 配置一个key过期事件的监听器 package com.shinedata.config.redis; import

  • 基于Redis实现延时队列的优化方案小结

    目录 一.延时队列的应用 二.延时队列的实现 三.总结 一.延时队列的应用 近期在开发部门的新项目,其中有个关键功能就是智能推送,即根据用户行为在特定的时间点向用户推送相应的提醒消息,比如以下业务场景: 在用户点击充值项后,半小时内未充值,向用户推送充值未完成提醒. 在用户最近一次阅读行为2小时后,向用户推送继续阅读提醒. 在用户新注册或退出应用N分钟后,向用户推送合适的推荐消息. … 上述场景的共同特征就是在某事件触发后延迟一定时间后再执行特定任务,若事件触发时间点可知,则上述逻辑也可等价于在

  • 基于Redis延迟队列的实现代码

    使用场景 工作中大家往往会遇到类似的场景: 1.对于红包场景,账户 A 对账户 B 发出红包通常在 1 天后会自动归还到原账户. 2.对于实时支付场景,如果账户 A 对商户 S 付款 100 元,5秒后没有收到支付方回调将自动取消订单. 解决方案分析 方案一: 采用通过定时任务采用数据库/非关系型数据库轮询方案. 优点: 1. 实现简单,对于项目前期这样是最容易的解决方案. 缺点: 1. DB 有效使用率低,需要将一部分的数据库的QPS分配给 JOB 的无效轮询. 2. 服务资源浪费,因为轮询需

  • 详解Java如何实现基于Redis的分布式锁

    前言 单JVM内同步好办, 直接用JDK提供的锁就可以了,但是跨进程同步靠这个肯定是不可能的,这种情况下肯定要借助第三方,我这里实现用Redis,当然还有很多其他的实现方式.其实基于Redis实现的原理还算比较简单的,在看代码之前建议大家先去看看原理,看懂了之后看代码应该就容易理解了. 我这里不实现JDK的java.util.concurrent.locks.Lock接口,而是自定义一个,因为JDK的有个newCondition方法我这里暂时没实现.这个Lock提供了5个lock方法的变体,可以

  • 基于redis实现定时任务的方法详解

    前言 业务中碰到的需求(抽象描述一下):针对不同的用户能够实现不同时间的间隔循环任务.比如在用户注册成功24小时后给用户推送相关短信等类似需求. 使用crontab?太重,且基本不现实,不可能给每一个用户在服务器上生成一个定时任务. 定时轮询?IO频繁且效率太低 想到经常的使用的redis可以设置缓存时间,应该会有过期的事件通知吧,查了一下文档,果然有相关配置,叫做"键空间事件通知".具体说明可参考官方文档. 技术栈 redis / nodeJs / koa 技术重难点 开启redis

随机推荐