Redis-1-format()方法

startFormat()逻辑

startFormat:参数校验与初始化 -- 防重复提交控制 -- 清理旧排版结果 -- 设置任务状态 -- 保存初始状态 -- 异步执行排版任务 -- 日志记录与返回

1. FormatService中:startFormat()

java 复制代码
 public void startFormat(StartFormatRequest request) {
        String nodeId = request.getNodeId();
        Integer styleId = request.getStyleId();
        Long userId = SecurityUtils.getCurrentUserId();

        // 1. 参数校验与初始化: 校验排版样式(fromCode会在styleId无效时抛出异常)
        LayoutStyle.fromCode(styleId);
        // 2.防重复提交控制:检查是否正在处理中.
        // 通过 Redis 检查当前用户是否正在处理相同文件的排版任务,避免重复提交.
        String taskKey = FORMAT_TASK_KEY_PREFIX + userId + ":" + styleId + ":" + nodeId;
        String currentStatus = stringRedisTemplate.opsForValue().get(taskKey);//检查是否正在处理中
        if (TASK_PROCESSING.equals(currentStatus)) {
            log.info("FormatService##startFormat-1,文件正在排版处理中,请勿重复提交,nodeId={},styleId={}", nodeId, styleId);
            throw new BizException(ErrorCode.BUSINESS_ERROR, "文件正在排版处理中,请勿重复提交");
        }
        // ....

        // 3. 清理该文件的旧排版结果(同一userId + sourceNodeId 只保留最新一次)
        // 调用 cleanupOldFormatResults 方法删除用户历史排版结果,确保只保留最新一次排版数据。
        cleanupOldFormatResults(userId, nodeId);
        // 4.设置任务状态为处理中(24小时过期)
        // 在 Redis 中设置任务状态为"处理中"(PROCESSING),并设置 24 小时过期时间
        stringRedisTemplate.opsForValue().set(taskKey, TASK_PROCESSING, 24, TimeUnit.HOURS);
        // 5. 保存初始状态:立即保存"排版中"状态的结果项,让前端可以立即查询到
        // 调用 saveFormattingResultItem 方法立即保存"排版中"状态的结果项,供前端实时查询
        saveFormattingResultItem(nodeId, fileName, userId);
        // 6. 异步执行排版任务:通过ApplicationContext获取代理对象,调用doFormatAsync方法异步执行排版逻辑
        // 通过 ApplicationContext 获取代理对象调用,触发 @Async 异步执行
        // 直接调用 doFormatAsync() 不会走 AOP 代理,@Async 不生效
        // 注意:Spring 使用 JDK 动态代理,需要通过接口类型获取 Bean
        FormatService proxy = applicationContext.getBean(FormatService.class);
        proxy.doFormatAsync(styleId, null, nodeId, fileId, fileName, userId, taskKey);
        // 7.日志记录与返回:方法立即返回,前端通过轮询 query 接口查询排版状态
        // 记录关键操作日志,方法执行后立即返回,前端通过轮询接口查询排版状态
        log.info("FormatService##startFormat-6,排版任务已提交异步执行,nodeId={}", nodeId);
    }

(1)设置任务状态 :①目的:防止重复提交任务。②实现方式:通过 Redis 的 stringRedisTemplate.opsForValue().set(taskKey, TASK_PROCESSING, 24, TimeUnit.HOURS) 设置一个键值对;taskKey 是基于用户 ID、样式 ID 和文件节点 ID 生成的唯一标识;值为 TASK_PROCESSING("PROCESSING"),表示当前任务正在进行中;过期时间为 24 小时,确保任务状态不会永久占用 Redis。③作用:在方法开头检查该键是否存在且值为 TASK_PROCESSING,如果存在则抛出异常,提示用户"文件正在排版处理中,请勿重复提交";避免同一用户对同一文件重复发起排版任务。
(2) 保存初始状态 :①目的:记录排版任务的初始信息,供前端实时查询。②实现方式:调用 saveFormattingResultItem 方法,将"排版中"状态的结果项保存到 Redis;该方法会创建一个 FormatResultItem 对象,状态为 FORMATTING,并将其序列化后存储到 Redis 中;同时更新用户与文件的映射关系(通过 FORMAT_USER_KEY_PREFIX 和 FORMAT_SOURCE_KEY_PREFIX)。③作用:提供给前端查询接口使用,前端可以通过轮询获取当前任务的状态(如"排版中");即使异步任务尚未完成,前端也能立即感知到任务已启动。

(3)清理旧版结果:为了清除与当前用户和原文件相关的历史排版任务数据。包括以下几类历史数据:①旧排版结果项详情:清理 Redis 中存储的旧排版结果项(FormatResultItem),这些数据以 format:item:{resultNodeId} 为键,包含排版任务的状态、文件名等信息;②用户与原文件的映射关系:清理 format:source:{userId}:{sourceNodeId} 键对应的 Set 数据,该 Set 存储了原文件的所有排版结果 resultNodeId 列表;③从 format:user:{userId} 键对应的 Set 中移除原文件的 sourceNodeId,表示该用户不再关联此原文件的排版记录。

相关推荐
loong_XL5 分钟前
决策模型做内容安全检测:从踩坑到上线
数据库·安全·jev·决策模型
这个DBA有点耶11 分钟前
数据库双轨并行实战:全量并行策略、增量延迟控制、双向回切与一致性校验
数据库·架构·dba
adinnet202642 分钟前
保单、赔付与渠道问数:保险经营数据如何实现按需查询
大数据·数据库·人工智能
云贝贝贝1 小时前
PostgreSQL 分区表:从设计到运维,大表不再卡
运维·数据库·postgresql
oradh1 小时前
Oracle固定执行计划的方法---SQL Plan Baseline
数据库·sql·oracle
数据库小学妹1 小时前
数据库高可用演练怎么做?稳态定义、注入点与中止条件
数据库·rto·高可用架构·运维体系·故障演练·容灾切换
zyseo81 小时前
谷歌SEO 站内搜索优化实战:把站内搜索词变成关键词金矿
java·服务器·数据库
qq_401700411 小时前
Qt 串口/网口通信:Hex 与 ASCII 编码转换深度指南
开发语言·数据库·qt
码爸1 小时前
多源异构数据库实时同步至 Doris
数据库·flink·scala
王大傻09281 小时前
堆叠注入(Stacked Queries Injection)详解:原理、利用与防御
服务器·网络·数据库·web安全·网络安全