知识库文档管理接口
前面几篇文章把文档的上传和分块处理讲完了:upload 接口负责把文件存到对象存储、元数据存到数据库,状态设为 PENDING;startChunk 接口通过 MQ 异步触发分块处理,把文档切分成 chunk 并写入向量库。这两个接口构成了文档从入库到可检索的完整链路。
文档入库之后,还需要一套管理接口来控制文档的生命周期:删除不需要的文档、更新文档配置、临时下线某个文档等。这篇文章聚焦三个事务型管理接口:delete(删除文档)、update(更新文档信息)、enable(启用/禁用文档)。
这三个接口看起来简单,但背后涉及分布式系统的数据一致性、事务边界设计、幂等性保障等核心问题。
三个接口概览
在深入每个接口之前,先用一张表格横向对比它们的关键特征:
| 维度 | delete | update | enable |
|---|---|---|---|
| HTTP 方法 | DELETE | PUT | PATCH |
| 接口路径 | /knowledge-base/docs/{doc-id} | /knowledge-base/docs/{docId} | /knowledge-base/docs/{docId}/enable |
| 核心职责 | 删除文档及所有关联数据 | 更新文档信息和配置 | 启用/禁用文档 |
| 破坏性 | 高(逻辑删除) | 中(配置变更) | 低(状态切换) |
| 事务范围 | DB + 向量库 + 文件 | DB + 调度任务 | DB + chunk + 调度 |
| 幂等性 | 非严格幂等 | 部分幂等 | 严格幂等 |
| 关联清理 | chunk/schedule/log/vector/file | 无 | 无 |
| 调度同步 | 删除调度任务 | 同步调度配置 | 同步调度状态 |
| 状态校验 | 禁止 RUNNING | 禁止 RUNNING | 禁止 RUNNING |
1. 共同特征
三个接口有几个明显的共同点:
-
都使用事务保护:数据库操作(document、chunk、schedule、chunk_log 表)在 Spring 事务中,保证 ACID 特性。多表操作要么全部成功,要么全部回滚。delete 和 update 使用
@Transactional注解声明式事务,enable 使用编程式事务(TransactionOperations)以便把耗时的 embedding 调用移到事务外,缩短事务持有时间。 -
都检查
status != RUNNING:三个接口在执行前都会检查文档是否处于 RUNNING 状态,如果是则直接抛异常。 -
都涉及多表联动:不只是更新 document 表,还会联动更新 chunk、schedule、chunk_log 等关联表。
1.1 为什么要检查 RUNNING 状态
分块处理是异步的,用户点击执行分块后,startChunk 接口立即返回,实际的分块任务在 MQ 消费者中执行,可能需要几分钟。如果允许在分块运行时删除或修改文档,会导致:
-
分块任务找不到文档记录:delete 接口把文档删了,分块任务执行到一半发现文档不存在,抛异常。
-
分块任务使用旧配置:update 接口把 chunkStrategy 从
fixed_size改成structure_aware,但分块任务已经开始执行,用的还是旧配置,最终写入的 chunk 和配置不一致。 -
向量库和数据库数据不一致:分块任务正在写向量库,delete 接口把数据库记录删了,向量库里留下孤儿向量。
所以三个接口都要先检查状态,确保文档不在分块中,才能安全地执行变更操作。