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),该方案对批量路径同样适用。

关联

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

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions