Files
pj_service_cloud/pjcloud-common/pjcloud-common-async-task/README.md
T
2026-10-21 19:39:59 +08:00

80 lines
3.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 通用异步任务模块
`pjcloud-common-async-task` 提供可由各业务模块复用的异步事务执行、Redis 进度保存和统一进度查询接口。
## 接入方式
业务模块增加依赖后,Spring Boot 会自动装配 `AsyncTaskExecutorService`、`AsyncTaskProgressService` 和查询接口:
```xml
<dependency>
<groupId>com.bsd</groupId>
<artifactId>pjcloud-common-async-task</artifactId>
</dependency>
```
提交任务时由业务方指定稳定的 Redis 业务命名空间、展示名称和总数。接口同步返回初始进度,业务动作进入公共模块的受控专用线程池并在单个事务中执行:
```java
AsyncTaskProgressVO progress = asyncTaskExecutorService.submit(
"user:import:teacher", "老师用户导入", users.size(),
reporter -> users.forEach(user -> {
importUser(user);
reporter.advance("正在导入:" + user.getName());
}));
```
导出等需要在成功终态返回结果文件的任务使用兼容扩展入口,原有无结果任务的 `submit` 契约保持不变:
```java
AsyncTaskProgressVO progress = asyncTaskExecutorService.submitWithResult(
"user:export", "用户信息导出", 3, reporter -> {
String fileUrl = exportAndUpload(reporter);
return AsyncTaskResult.file(fileUrl, "用户信息.xlsx");
});
```
查询数据本身耗时且提交接口需要立即返回时,可以先用大于零的占位总数创建任务,再在异步线程查询完成后更新真实总数:
```java
AsyncTaskProgressVO progress = asyncTaskExecutorService.submitWithResult(
"user:export", "用户信息导出", 1, reporter -> {
List<UserVO> users = queryUsers();
reporter.updateTotal(users.size(), "已查询 " + users.size() + " 位用户");
return exportUsers(users, reporter);
});
```
调用端统一轮询:
```text
GET /async-task/progress?redisKey={业务命名空间}&taskId={任务ID}
```
## Redis 租户 Key 约定
项目 Redis 基础设施会根据当前租户上下文自动为 Redis Key 增加租户前缀。业务代码只负责定义业务命名空间和业务唯一标识,**不需要也不得再次手工拼接 `tenantId`**。
正确的业务 Key:
```text
async:task:progress:user:import:teacher:{userId}:{taskId}
```
错误的业务 Key:
```text
async:task:progress:user:import:teacher:{tenantId}:{userId}:{taskId}
```
错误示例会导致租户维度重复出现在最终 Redis Key 中,并可能造成同一业务在不同调用方式下无法读取彼此写入的数据。
“业务 Key 不拼接租户 ID”不代表异步线程不需要租户上下文。异步任务在访问 Redis、数据库或其他租户资源前,仍需恢复 `TenantContextHolder`,并在任务结束后清理上下文。本模块执行器已经统一处理这一步,业务动作不应重复设置租户上下文。
## 事务与进度语义
- 整个业务动作由一个 Spring 事务包裹,业务抛出异常时整体回滚。
- `completed` 表示当前执行位置;失败并回滚时不代表最终成功写入数量。
- Redis 进度默认保留 24 小时,供页面刷新或短时重连后继续查询。
- 任务进度按当前登录用户隔离,调用端不能查询其他用户创建的任务。