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,表示该用户不再关联此原文件的排版记录。

相关推荐
辞旧 lekkk7 小时前
【Qt】信号和槽
linux·开发语言·数据库·qt·学习·mysql·萌新
我是唐青枫8 小时前
终于不用手搓两级缓存了!C#.NET HybridCache 详解:L1 L2、标签失效与防击穿实战
redis·缓存·c#·.net
2301_809204708 小时前
JavaScript中严格模式use-strict对引擎解析的辅助.txt
jvm·数据库·python
zjy277779 小时前
mysql如何选择合适的索引类型_mysql索引设计实战
jvm·数据库·python
笨蛋不要掉眼泪9 小时前
Mysql架构揭秘:update语句的执行流程
数据库·mysql·架构
万邦科技Lafite9 小时前
京东item_get接口实战案例:实时商品价格监控全流程解析
java·开发语言·数据库·python·开放api·淘宝开放平台
秋910 小时前
ruoyi项目更换为mysql9.7.0数据库
数据库
Andya_net10 小时前
MySQL | MySQL 8.0 权限管理实践-精确赋予库、表只读等权限
android·数据库·mysql
筑梦之路11 小时前
harbor数据库报错权限异常如何处理——筑梦之路
数据库·harbor
czlczl2002092512 小时前
理解 MySQL 行锁:两阶段锁协议与热点更新优化
数据库·mysql