批量操作容错的核心是“错得清楚、停得可控、续得可靠”,即通过单条数据级try-catch实现失败隔离,按错误类型分级处理(可恢复跳过、数据级校验失败归类、系统级错误立即中断),并结构化返回失败详情,配合分段提交、数据库忽略冲突等底层机制提升健壮性。

批量操作容错的核心不是“不报错”,而是“错得清楚、停得可控、续得可靠”。关键在于把错误隔离在单个数据单元内,不让它蔓延成整个批次的中断。
用 try-catch 包裹单条处理逻辑
这是最直接、最可控的基础手段。每条数据独立执行、独立捕获、独立记录,天然实现失败隔离。
- 不要把整个 for 循环或 stream 操作包在一个大 try-catch 里——那样一旦出错就全停
- 每个 process(data) 调用都应有自己的 try-catch 块,捕获后仅记录日志或存入失败列表,不 throw 向上传播
- 推荐记录:数据标识(如 ID、编号)、错误类型、堆栈摘要、时间戳,便于后续人工复核或自动重试
区分错误类型,决定是否跳过或终止
不是所有异常都该被“吞掉”。要根据业务语义做判断:
- 可恢复错误:如网络超时、临时锁冲突、下游服务抖动——可记录后跳过,或加入延迟重试队列
- 数据级错误:如字段为空、格式非法、主键冲突——属于脏数据问题,应记录并明确归类为“校验失败”,避免污染目标系统
- 系统级错误:如数据库连接彻底断开、磁盘满、内存溢出——这类需立即中断整个批次,防止雪崩,同时触发告警
结构化收集失败结果,反馈给调用方
用户或上游系统需要知道“谁没干成、为什么没干成”,不能只返回“成功 997 条,失败 3 条”这种模糊信息。
- 定义统一的响应结构,例如:
{ "successCount": 997, "failures": [{"id": "U1001", "reason": "email_invalid", "message": "邮箱格式不合法"}, ...] } - 失败项尽量保留原始输入片段(脱敏后),方便定位上下文
- 对 Web 接口,HTTP 状态码仍用 200(因整体请求成功),把失败详情放在响应体中;避免用 500 混淆语义
配合底层机制提升健壮性
代码层容错之外,还需借力基础设施降低失败概率:
- 数据库写入时善用
INSERT IGNORE或ON DUPLICATE KEY UPDATE,避免单条主键冲突导致整批回滚 - Elasticsearch bulk 请求必须检查每个子项的
error字段——HTTP 200 不代表全成功 - 大事务慎用长循环+单事务提交;可分段提交(如每 100 条 commit 一次),既控内存又限影响范围
















