Skip to content

bulkCreate / upsert 仍会逐次烧号:#5495 的重播种只落在 create(),批次语义是独立决策 #6943

Description

@os-zhuang

一句话说明

#5495(PR #6932)让 SqlDriver.create() 在唯一冲突后重播种陈旧的自增号计数器并有界重试,于是"每次失败烧一个号"在该路径上不可达。bulkCreate()upsert() 没有拿到这个修复 —— 两者同样调用 fillAutoNumberFields,碰撞后同样没有重播种,因此在同一个陈旧计数器上仍会逐次烧号并把请求打失败。

#5495 的 dev 在范围审计中记录,刻意未顺手修(PD #10)。

为什么不是 #5495 的一部分

不是遗漏,是裁向边界:批内逐行重试会改变批次语义 —— 部分成功如何呈现、事务边界怎么划、失败行是否回滚整批。这些都不是 #5495 那条"单行 create 的陈旧计数器"裁向能顺带决定的,需要单独定夺。

前提(#5495 已实测,可直接继承)

  • 计数器陈旧的成因:播种只在 getNextSequenceValueif (!existing) 分支跑一次,此后不再读数据表;任何绕过 fillAutoNumberFields 落地的行(isSystem 种子回放、preserveAudit 导入、直接 SQL)都不抬序列。
  • 因此 bulkCreate / upsert 在同一张表上会遇到与 create 完全相同的陈旧,只是收口点不同。
  • 判据不能用错误报文取冲突列:uniqueViolationColumn() 在带租户的自增号上恒为 undefined(复合键 → soleColumn 拒答;ADR-0120 D3 的表达式索引 → SQLite 报索引名 → SQLITE_INDEX_FORM 拒答;MySQL 无该 limb)。fix(driver-sql): re-seed a stale autonumber counter instead of burning a number per failed create (#5495) #6932 因此改用数据探测(autoNumberValueExists),该方案对批量路径同样适用。

关联

未认领,仅作记录,定级交分诊。

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions