当前位置: 首页 > news >正文

关于对逾期提醒的定时任务~改进完善

Spring Boot 中实现到期提醒任务的定时Job详解

在金融或借贷系统中,到期提醒是常见的功能需求。通过定时任务,可以定期扫描即将到期的借款记录,并生成或更新提醒信息。本文基于提供的三个JobHandler类(FarExpireRemindJob、MidExpireRemindJob 和 RecentExpireRemindJob),详细分析其实现逻辑。这些类使用Spring Boot的组件注解(@Component),并实现了JobHandler接口(假设这是自定义的定时任务接口),结合MyBatis-Plus的QueryWrapper进行数据库操作。代码涉及借款入库(LoanInDO)、借款出库(LoanOutDO)和提醒记录(RemindExpireDO)的处理。

本文将逐一拆解每个类的代码结构、核心逻辑、潜在优化点和注意事项,确保覆盖所有提供的代码片段。假设这些Job是集成在XXL-JOB或类似调度框架中的定时任务。

1. 整体功能概述
  • FarExpireRemindJob:负责远期到期提醒(默认30天)。扫描即将到期的借款记录,生成提醒记录,并更新借款记录的提醒标志。
  • MidExpireRemindJob:负责中期到期提醒(默认15天)。更新已存在的提醒记录,调整提醒状态和时间。
  • RecentExpireRemindJob:负责近期到期提醒(默认7天)。类似于中期提醒,更新提醒记录的状态和时间。 这些Job通过参数(param)支持自定义天数,支持事务回滚(仅FarExpireRemindJob有@Transactional注解),并返回执行结果字符串,便于日志记录或监控。

依赖的Mapper(如LoanInMapper、RemindExpireMapper等)使用MyBatis-Plus进行CRUD操作。DO类(如LoanInDO)是数据库实体,包含字段如id、custId、expireTime等。

2. FarExpireRemindJob 详细分析

这个类是三个Job中最复杂的,涉及多表操作和批量更新。它的目的是在借款到期前一定天数(默认30天)生成提醒记录,并标记借款记录已提醒。

代码结构:

  • 类注解和依赖注入:

  • @Component
    public class FarExpireRemindJob implements JobHandler {@Autowiredprivate LoanInMapper loanInMapper;@Autowiredprivate RemindExpireMapper remindExpireMapper;@Autowiredprivate LoanOutMapper loanOutMapper;

    • @Component:将类注册为Spring Bean,便于调度框架注入和调用。
    • 注入三个Mapper:用于查询和更新借款入库、出库和提醒表。
  • execute方法(核心执行逻辑):

@Override
@Transactional(rollbackFor = Exception.class)
public String execute(String param) throws Exception {// 到期提醒默认值int day = (StringUtils.isEmpty(param)) ? 30 : Integer.parseInt(param);List<LoanInDO> loanInDOList = loanInMapper.selectList(new QueryWrapperX<LoanInDO>().eq("overdue_flag", 0).eq("expire_remind_flag", 0).le("expire_time", LocalDate.now().plusDays(day)));List<LoanOutDO> loanOutDOList = loanOutMapper.selectList(new QueryWrapper<LoanOutDO>().eq("overdue_flag", 0).eq("expire_remind_flag", 0).le("expire_time", LocalDate.now().plusDays(day)));
  • 解析参数:如果param为空,默认day=30,否则转换为整数。
  • 查询借款入库记录:使用QueryWrapperX(MyBatis-Plus扩展)过滤未逾期(overdue_flag=0)、未提醒(expire_remind_flag=0)、到期时间 <= 当前日期 + day 的记录。
  • 类似查询借款出库记录。注意:QueryWrapperX可能是自定义的Wrapper,支持更灵活的查询。
    List<RemindExpireDO> remindExpireDOList = new ArrayList<>();loanInDOList.forEach(loanInDO -> {loanInDO.setExpireRemindFlag(1);RemindExpireDO remindExpireDO = RemindExpireDO.builder().loanId(loanInDO.getId()).custId(loanInDO.getCustId()).custCode(loanInDO.getCustCode()).custName(loanInDO.getCustName()).contractCode(loanInDO.getContractCode()).amount(loanInDO.getAmount()).balance(loanInDO.getBalance()).beginTime(loanInDO.getBeginTime()).expireTime(loanInDO.getExpireTime()).remindTime(LocalDateTime.now()).showFlag(1).remindStatus(day).remindFlag(1).userName(loanInDO.getUserName()).userId(loanInDO.getUserId()).deptName(loanInDO.getDeptName()).deptId(loanInDO.getDeptId()).build();loanInDO.setExpireRemindFlag(1);  // 重复设置,可能是笔误remindExpireDOList.add(remindExpireDO);});
  • 处理借款入库列表:遍历每个LoanInDO,设置expireRemindFlag=1(标记已提醒)。
  • 使用Lombok的builder模式创建RemindExpireDO,复制借款相关字段,并设置提醒时间、状态等。
  • 注意:loanInDO.setExpireRemindFlag(1); 出现了两次,第二次是多余的,可能为代码笔误,会导致无谓操作但不影响功能。
  • 添加到remindExpireDOList中。
    loanOutDOList.forEach(loanOutDO -> {loanOutDO.setExpireRemindFlag(1);RemindExpireDO remindExpireDO = RemindExpireDO.builder()// ... 与入库类似,复制字段 ....build();loanOutDO.setExpireRemindFlag(1);  // 同样重复设置remindExpireDOList.add(remindExpireDO);});

处理借款出库列表:逻辑与入库完全相同,包括重复的setExpireRemindFlag。

    if (!loanInDOList.isEmpty()) {loanInMapper.updateBatch(loanInDOList);}if (!loanOutDOList.isEmpty()) {loanOutMapper.updateBatch(loanOutDOList);}if (!remindExpireDOList.isEmpty()) {remindExpireMapper.insertBatch(remindExpireDOList);}return String.format("已产生 %s 条到期提醒", remindExpireDOList.size());
}
    • 批量更新借款记录(如果列表非空)。
    • 批量插入提醒记录。
    • 返回结果字符串,报告生成的提醒条数。
    • @Transactional:确保所有操作在事务中,如果异常则回滚,防止数据不一致。

分析与优化点:

  • 优点:批量操作高效,避免了循环中的单条更新;事务保障数据一致性;参数化day支持灵活配置。
  • 潜在问题:如果借款记录量大,查询和遍历可能耗时,需要监控性能。重复的setExpireRemindFlag是小bug,可移除第二次调用。未处理param解析异常(e.g., 非数字),建议添加try-catch。
  • 改进建议:添加日志记录(e.g., SLF4J);如果day很大,查询条件可优化索引(expire_time字段应有索引);考虑分页查询以防内存溢出。
3. MidExpireRemindJob 详细分析

这个Job专注于更新中期提醒(默认15天),不生成新记录,只更新现有提醒的status和time。

代码结构:

  • 类注解和依赖注入:
@Component
public class MidExpireRemindJob implements JobHandler {@Autowiredprivate RemindExpireMapper remindExpireMapper;
    • 类似前者,只注入提醒Mapper。
  • execute方法:
@Override
public String execute(String param) throws Exception {int day = (StringUtils.isEmpty(param)) ? 15 : Integer.parseInt(param);List<RemindExpireDO> remindExpireDOS = remindExpireMapper.selectList(new QueryWrapperX<RemindExpireDO>().between("expire_time",LocalDate.now().plusDays(day),LocalDate.now().plusDays(day + 1)));remindExpireDOS.forEach(remindExpireDO -> {remindExpireDO.setRemindTime(LocalDateTime.now());remindExpireDO.setRemindStatus(day);});if (!remindExpireDOS.isEmpty()) {remindExpireMapper.updateBatch(remindExpireDOS);}return String.format("更新了 %d 条提醒", remindExpireDOS.size());
}
    • 解析day,默认15。
    • 查询提醒记录:到期时间在 [当前+day, 当前+day+1) 之间,使用between条件。
    • 遍历更新:设置当前提醒时间和status=day。
    • 批量更新,如果非空。
    • 返回更新条数。

分析与优化点:

  • 优点:简单高效,只更新必要字段;between条件精确匹配特定天窗。
  • 潜在问题:未加@Transactional,如果更新失败无回滚(与其他Job不一致)。查询未过滤已逾期或已处理记录,可能重复更新。
  • 改进建议:添加事务注解;添加过滤条件如.eq("remindStatus", > day) 以避免重复;考虑day的边界(如day=0时)。
4. RecentExpireRemindJob 详细分析

与MidExpireRemindJob几乎相同,仅默认day=7和返回字符串略不同,用于近期提醒。

代码结构:

  • 类注解和依赖注入: 同Mid,仅注入RemindExpireMapper。
  • execute方法:
@Override
public String execute(String param) throws Exception {int day = (StringUtils.isEmpty(param)) ? 7 : Integer.parseInt(param);List<RemindExpireDO> remindExpireDOS = remindExpireMapper.selectList(new QueryWrapperX<RemindExpireDO>().between("expire_time",LocalDate.now().plusDays(day),LocalDate.now().plusDays(day + 1)));remindExpireDOS.forEach(remindExpireDO -> {remindExpireDO.setRemindTime(LocalDateTime.now());remindExpireDO.setRemindStatus(day);});if (!remindExpireDOS.isEmpty()) {remindExpireMapper.updateBatch(remindExpireDOS);}return String.format("更新了 %d 条提醒记录", remindExpireDOS.size());
}
    • 逻辑完全一致,仅day默认7,返回消息为“提醒记录”。

分析与优化点:

  • 优点:代码复用性高,与Mid类似,便于维护。
  • 潜在问题:同Mid,无事务;可能与Mid重叠更新(如果day重合)。
  • 改进建议:合并Mid和Recent为一个Job,通过param区分;添加唯一性检查避免多Job冲突。
5. 整体系统设计与注意事项
  • 定时调度:这些Job适合每天运行一次(e.g., 凌晨)。FarJob生成初始提醒,Mid/Recent逐步更新status,形成多级提醒(如30→15→7天)。
  • 数据一致性:Far有事务,其他无,建议统一添加。所有Job使用LocalDate.now(),注意时区。
  • 性能考虑:批量操作好,但大表需索引(expire_time、flags)。错误处理:param非数字时抛异常,可加校验。
  • 扩展性:可添加短信/邮件通知在更新后;DO类字段丰富,支持报表。
  • 测试建议:单元测试查询条件;集成测试事务回滚。

通过这些Job,可以实现自动化到期提醒系统。如果需要完整项目代码或进一步优化,欢迎评论交流!


文章转载自:

http://mMZxpEDW.wtcyz.cn
http://8JHKl30O.wtcyz.cn
http://r0sJyZBn.wtcyz.cn
http://SvAp08Ft.wtcyz.cn
http://a5GnA43i.wtcyz.cn
http://urZT6jws.wtcyz.cn
http://KFt6rSHX.wtcyz.cn
http://yKOh5840.wtcyz.cn
http://Fl815aNc.wtcyz.cn
http://MHyKx0LM.wtcyz.cn
http://NeSp85uY.wtcyz.cn
http://6Cz9cDQO.wtcyz.cn
http://v0QhHv1R.wtcyz.cn
http://DEWXRRIK.wtcyz.cn
http://tdIpJSmL.wtcyz.cn
http://F39iipMd.wtcyz.cn
http://nKRaIBmu.wtcyz.cn
http://tHHVrNdE.wtcyz.cn
http://g5Yp749E.wtcyz.cn
http://wVTYhp7Z.wtcyz.cn
http://fpNusoAy.wtcyz.cn
http://0WRnPQ90.wtcyz.cn
http://dN1yQD3H.wtcyz.cn
http://lWnrRInO.wtcyz.cn
http://CW93Oxgx.wtcyz.cn
http://qXIY2TaU.wtcyz.cn
http://bpbNfYWy.wtcyz.cn
http://HTCRHpst.wtcyz.cn
http://rNSUDB7S.wtcyz.cn
http://Y7w7GK7w.wtcyz.cn
http://www.dtcms.com/a/373336.html

相关文章:

  • BKY(莱德因):基于线粒体靶向的细胞级御龄科学实践
  • 学习日记-SpringMVC-day50-9.8
  • VUE3加载cesium,导入czml的星座后页面卡死BUG 修复
  • Redis集群——redis cluster(去中心化)
  • HCIE安全为什么是T0级别的选项?
  • IDEA开启并配置Services窗口(一个项目开启多个项目运行窗口并且显示端口)
  • Sourcetree使用
  • 【Docker】Docker安装
  • 个人日记系统00
  • 20.42 QLoRA微调实战:四层提示工程让批量数据生成错误率跌破0.5%
  • S32K3平台eMIOS 应用说明
  • iOS 开发入门指南-HelloWorld
  • HCIE数通/云计算真机实验机架展示
  • 【.Net技术栈梳理】04-核心框架与运行时(线程处理)
  • 量化金融|基于算法和模型的预测研究综述
  • HarmonyOS 数据处理性能优化:算法 + 异步 + 分布式实战
  • 1304. 和为零的 N 个不同整数
  • Java 集合Collection—List
  • leetcode9(跳跃游戏)
  • 在UnionTech OS Server 20 (统信UOS服务器版) 上离线安装PostgreSQL (pgsql) 数据库
  • Azure Logic App 与 Azure Function 对比分析
  • 房屋安全鉴定注意事项
  • 【Go】:mac 环境下GoFrame安装开发工具 gf-cli——gf_darwin_arm64
  • 知识竞赛活动舞台道具全面指南
  • Linux《进程信号(下)》
  • 力扣.1054距离相等的条形码力扣767.重构字符串力扣47.全排列II力扣980.不同路径III力扣509.斐波那契数列(记忆化搜索)
  • 区块链:重构企业数字化的信任核心与创新动力
  • 【系统架构设计师(22)】面向服务的软件架构风格
  • Google Play账户与App突遭封禁?紧急应对与快速重构上架策略
  • 操作系统进程/线程的状态与转换