2.3 KiB
2.3 KiB
通用异步任务模块
pjcloud-common-async-task 提供可由各业务模块复用的异步事务执行、Redis 进度保存和统一进度查询接口。
接入方式
业务模块增加依赖后,Spring Boot 会自动装配 AsyncTaskExecutorService、AsyncTaskProgressService 和查询接口:
<dependency>
<groupId>com.bsd</groupId>
<artifactId>pjcloud-common-async-task</artifactId>
</dependency>
提交任务时由业务方指定稳定的 Redis 业务命名空间、展示名称和总数。接口同步返回初始进度,业务动作进入公共模块的受控专用线程池并在单个事务中执行:
AsyncTaskProgressVO progress = asyncTaskExecutorService.submit(
"user:import:teacher", "老师用户导入", users.size(),
reporter -> users.forEach(user -> {
importUser(user);
reporter.advance("正在导入:" + user.getName());
}));
调用端统一轮询:
GET /async-task/progress?redisKey={业务命名空间}&taskId={任务ID}
Redis 租户 Key 约定
项目 Redis 基础设施会根据当前租户上下文自动为 Redis Key 增加租户前缀。业务代码只负责定义业务命名空间和业务唯一标识,不需要也不得再次手工拼接 tenantId。
正确的业务 Key:
async:task:progress:user:import:teacher:{userId}:{taskId}
错误的业务 Key:
async:task:progress:user:import:teacher:{tenantId}:{userId}:{taskId}
错误示例会导致租户维度重复出现在最终 Redis Key 中,并可能造成同一业务在不同调用方式下无法读取彼此写入的数据。
“业务 Key 不拼接租户 ID”不代表异步线程不需要租户上下文。异步任务在访问 Redis、数据库或其他租户资源前,仍需恢复 TenantContextHolder,并在任务结束后清理上下文。本模块执行器已经统一处理这一步,业务动作不应重复设置租户上下文。
事务与进度语义
- 整个业务动作由一个 Spring 事务包裹,业务抛出异常时整体回滚。
completed表示当前执行位置;失败并回滚时不代表最终成功写入数量。- Redis 进度默认保留 24 小时,供页面刷新或短时重连后继续查询。
- 任务进度按当前登录用户隔离,调用端不能查询其他用户创建的任务。