Springboot 定时任务分布式下幂等性解决方案

 更新时间:2023年07月05日 09:51:36   作者:lovoo  
这篇文章主要介绍了Springboot定时任务分布式下幂等性如何解决,本文通过示例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

一、概述:

在分布式环境下,定时任务的幂等性问题需要考虑多个节点之间的数据一致性和事务处理。

一种解决方法是使用分布式锁来保证同一时间只有一个节点能够执行该任务。具体实现可以使用Redis或Zookeeper等分布式协调工具提供的分布式锁功能。

另一种解决方法是使用消息队列来保证任务的幂等性。当一个节点执行任务时,先将任务发送到消息队列中,然后等待其他节点确认任务已经执行完毕后再进行后续操作。如果有节点出现故障或者网络异常导致任务未能成功执行,则可以重新发送任务并等待其他节点确认。

二、示例

如下图,有三台机器同时启动定时任务,将数据保存到Redis中,如何保证数据的幂等性?

在这里插入图片描述

解决方法–Redission分布式锁:

  • 在启动定时任务时,获取分布式锁,保证只有一个线程进入
  • 在获取锁之后,锁定10秒
  • 然后执行业务
  • 业务执行完成后,释放分布式锁
@Scheduled(cron = "*/10 * * * * ? ")    
public void uploadSeckillSkuLatest3Days() {
    // 重复上架无需处理
    log.info("上架秒杀的商品...");
    // 分布式锁(幂等性)
    RLock lock = redissonClient.getLock(SeckillConstant.UPLOAD_LOCK);
    try {
        lock.lock(10, TimeUnit.SECONDS);
        // 上架最近三天需要秒杀的商品
        seckillService.uploadSeckillSkuLatest3Days();
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        lock.unlock();
    }
}

上架商品时,判断redis是否有该商品,没有才上架

 Boolean hasKey = redisTemplate.hasKey(key);
 if (!hasKey) {
 }

全部代码

private void saveSessionInfos(List<SeckillSessionWithSkusTO> sessions) {
        if (!CollectionUtils.isEmpty(sessions)) {
            sessions.stream().forEach(session -> {
                // 1.遍历场次
                long startTime = session.getStartTime().getTime();// 场次开始时间戳
                long endTime = session.getEndTime().getTime();// 场次结束时间戳
                String key = SeckillConstant.SESSION_CACHE_PREFIX + startTime + "_" + endTime;// 场次的key
                // 2.判断场次是否已上架(幂等性)
                Boolean hasKey = redisTemplate.hasKey(key);
                if (!hasKey) {
                    // 未上架
                    // 3.封装场次信息
                    List<String> skuIds = session.getRelationSkus().stream()
                            .map(item -> item.getPromotionSessionId() + "_" + item.getSkuId().toString())
                            .collect(Collectors.toList());// skuId集合
                    // 4.上架
                    redisTemplate.opsForList().leftPushAll(key, skuIds);
                }
            });
        }
    }

到此这篇关于Springboot 定时任务分布式下幂等性如何解决的文章就介绍到这了,更多相关Springboot 幂等性内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Java8新特性Stream流详解

    Java8新特性Stream流详解

    Java8 Stream使用的是函数式编程模式,如同它的名字一样,它可以被用来对集合进行链状流式的操作,本文就将带着你如何使用 Java 8 不同类型的 Stream 操作,同时还将了解流的处理顺序,以及不同顺序的流操作是如何影响运行时性能的
    2023-07-07
  • java调用微信现金红包接口的心得与体会总结

    java调用微信现金红包接口的心得与体会总结

    这篇文章主要介绍了java调用微信现金红包接口的心得与体会总结,有需要的朋友可以了解一下。
    2016-11-11
  • java常用工具类 Date日期、Mail邮件工具类

    java常用工具类 Date日期、Mail邮件工具类

    这篇文章主要为大家详细介绍了java常用工具类,包括Date日期、Mail邮件工具类,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-05-05
  • jenkins+Maven从SVN上构建项目的方法

    jenkins+Maven从SVN上构建项目的方法

    这篇文章主要介绍了jenkins+Maven从SVN上构建项目,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-09-09
  • Spring Mybatis 基本使用过程(推荐)

    Spring Mybatis 基本使用过程(推荐)

    Mybatis是一个半自动ORM(Object Relational Mapping)框架,它可以简化数据库编程,让开发者更专注于SQL本身,本文给大家介绍Spring Mybatis 基本使用过程,感兴趣的朋友跟随小编一起看看吧
    2024-09-09
  • MyBatis超详细讲解如何实现分页功能

    MyBatis超详细讲解如何实现分页功能

    MyBatis-Plus 是一个 Mybatis 增强版工具,在 MyBatis 上扩充了其他功能没有改变其基本功能,为了简化开发提交效率而存在,本篇文章带用它实现分页功能
    2022-03-03
  • SpringBoot使用CORS解决无法跨域访问问题的具体步骤

    SpringBoot使用CORS解决无法跨域访问问题的具体步骤

    跨域问题指的是不同站点之间,使用 ajax 无法相互调用的问题,跨域问题本质是浏览器的一种保护机制,它的初衷是为了保证用户的安全,防止恶意网站窃取数据,本文给大家介绍了SpringBoot使用CORS解决无法跨域访问问题的具体步骤,需要的朋友可以参考下
    2025-05-05
  • SpringBoot3整合Druid数据源的实现过程

    SpringBoot3整合Druid数据源的实现过程

    文章介绍了一个基于Spring Boot 3的程序实现过程,包括创建项目、引入依赖、编写启动类、配置文件、Controller、启动测试以及问题解决,本文给大家介绍的非常详细,感兴趣的朋友跟随小编一起看看吧
    2025-11-11
  • Java 日期时间处理详解(API、格式化)

    Java 日期时间处理详解(API、格式化)

    在编程中,对日期和时间的处理是一个非常重要的方面,Java提供了丰富的类和工具来处理日期和时间,本文将对Java中的日期时间处理进行详细介绍,感兴趣的朋友跟随小编一起看看吧
    2026-01-01
  • java九九乘法表示例

    java九九乘法表示例

    这篇文章主要介绍了java九九乘法表示例,需要的朋友可以参考下
    2014-04-04

最新评论