Skip to content

objectql: 批插入部分成功 API——根治降级重写下 beforeInsert 钩子 at-least-once(#3152 跟进) #3172

Description

@os-zhuang

背景

#3152 在 PR #3161 中按"缓解而非根治"落地:

  • ✅ autonumber 移到校验之后——注定失败的批尝试不再消耗号段;
  • engine.insert JSDoc 明确 beforeInsert 为 at-least-once 语义(钩子需幂等);
  • 未根治:批中一行校验失败 → 整个 engine.insert(array) 抛错 → bulkWrite 降级逐行重跑完整 insert → 好行的 beforeInsert 钩子仍执行 2 次(副作用型钩子:发通知、计数器、外部 API 调用等重复执行)。

当时的结论(见 #3161 PR 描述):根治需要引擎级部分成功 API,超出 #3152 范围。本 issue 跟踪该根治。

方向

给批插入路径一个"部分成功"形态,让 bulkWrite 不再需要"整批失败 → 重跑整个 insert"这种放大钩子副作用的降级:

  • 候选 A:engine.insert(array, { partial: true }) 返回 per-row 结果({ok, record | error}[]),校验失败的行不再让整批抛错;好行只走一遍 hooks → 校验 → 驱动写入。
  • 候选 B:新增独立入口(如 engine.insertMany),旧的 insert(array) 语义保持不变(仍整批原子抛错),调用方(seed/import 的 writeBatch 闭包)切到新入口。
  • 无论哪种,坏行需在 beforeInsert 之后、驱动写入之前被剔除并报告,好行的钩子恰好执行 1 次;afterInsert / record-change 流程触发器行为保持不变(仍恰 1 次)。

需要评估的点:

验收标准

—— #3152 的根治跟进;缓解措施已随 PR #3161 合入。

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions