1. 背景:
有两个定时任务在特定时间触发,同时对数据进行操作,且任务之间存在并发执行的场景。主要涉及的表为 lingyejun_task,涉及到的操作有:数据插入、推送、状态更新和错误处理。
定时任务A负责生成数据,定时任务B负责将生成好的数据处理并推送到第三方系统,由于出问题的时候定时任务A生成数据是一条一条循环生成,并没有声明事务,所以会有一些不符合预期的情况发生,下面让我们详细看看。
2. 事件流程(简化描述):
-
10点:定时任务A执行,写入 3 条订单明细数据(其实一共有12条数据,但并未放到一个事务中)。导致定时任务B也在这个时间点触发的时候,任务B只能查到这 3 条数据并进行推送。由于并发,任务B在处理时错误地将这 3 条数据的状态更新为“已推送”,实际应该将12条数据全部推送完毕才应该改为已推送。这里已经生成了12条数据,只是在当时并发时,只把推送任务B触发前三条推送了,且推送成功了,后9条没推送。
-
11点:任务B执行时,将后面的9条数据进行了推送,但是下游系统有订单号唯一键校验,推送失败,将这9条数据更改为推送失败。在此时任务A又生成了 4 条新的数据。接着进行推送,推送了 4 条新生成的数据,推送失败,报错信息为:“没有满足
msg contains
逻辑”。由于错误,任务B按失败处理,并根据唯一键重新更新状态,将 4 条数据标记为失败。 -
12点:查询时,系统最终查到 16 条数据,任务再次推送数据。此时报错信息为:“Data is duplicated, please check”,任务按成功处理,并将状态更新为成功。然而,系统实际上只有前三条数据是成功推送的,后 13 条数据没有推送成功。
3. 问题分析:
-
并发问题:两个定时任务在相同或接近的时间点触发,导致数据写入、推送和状态更新操作的顺序出现了问题,造成了资源竞争和数据不一致。任务A和任务B可能试图同时处理相同的数据。
-
错误的状态更新:由于任务A的错误(将3条数据退单),任务2在执行时认为这些数据已经存在,因此没有进行正确的推送。最终导致状态更新和数据推送顺序错乱。
-
推送失败:11点任务B推送时,报错“没有满足
msg contains
逻辑”,这可能是由于并发导致的查询结果不一致,或者推送接口的逻辑判断出现了问题。 -
数据重复问题:12点再进行推送时,系统提示“Data is duplicated”,这说明系统检测到重复数据。实际上,这表明任务A和任务B的处理逻辑并未正确处理数据的唯一性或排他性,导致数据处理出现问题。
-
部分成功,部分失败:虽然最终显示“成功”,但实际上,只有前三条数据推送成功,其余13条数据失败。系统没有正确识别哪些数据推送成功,哪些失败,导致错误的状态更新。
4. 解决方案与优化建议:
-
同步机制:考虑使用同步机制(如分布式锁、任务队列)来确保两个任务不会同时操作相同的数据或资源,避免并发冲突。
- 可以使用 Redis 或数据库锁来控制任务的并发执行,确保任务之间不会相互干扰。
-
任务分隔与调度优化:对定时任务的执行进行错峰调度,避免两个任务在相同时间点执行。可以使用调度框架(如 Quartz)来优化任务的执行时机。
-
数据状态检查:在推送数据之前,进行严格的数据状态检查,确保数据状态正确且没有重复,避免出现状态更新错误。比如,在任务执行前,检查目标数据是否已存在并已被其他任务处理。
-
事务控制:使用数据库事务来保证数据一致性。对于涉及多步操作(如写入、更新、推送)的任务,可以考虑将其放入一个事务中,确保任务的一致性。如果某一部分操作失败,则回滚整个任务的执行。
-
推送逻辑的改进:推送失败时,采用更明确的错误处理和重试机制。避免因一次错误导致所有数据的失败标记。可以在推送过程中记录详细的错误信息,并根据具体的错误进行细化处理。
-
日志与监控:加强任务执行的日志记录和监控。对于每个定时任务,记录其执行的详细过程、成功与失败的情况、数据变更和状态更新等。通过日志分析可以帮助及时发现并解决问题。
-
异常捕获与重试机制:对推送失败进行合理的异常捕获和重试机制,避免一次错误导致整个流程的中断。
5. 总结:
本问题的核心是并发操作导致的资源竞争和数据一致性问题,主要体现在定时任务之间没有有效的同步和协调,导致数据写入、推送和状态更新的顺序错误。为解决这一问题,需要在任务执行时引入更严格的同步控制、事务管理和错误处理机制,同时优化任务调度和数据处理逻辑,确保并发任务间的数据一致性和稳定性。
本篇文章如有帮助到您,请给「翎野君」点个赞,感谢您的支持。
首发链接:https://www.cnblogs.com/lingyejun/p/18639756
标签:状态,并发,任务,数据处理,定时,推送,数据 From: https://www.cnblogs.com/lingyejun/p/18639756