Repository navigation
cherry-pick: Stop retried replicated writes from re-applying a duplicate that already committed (conflicts → v5.3) - #3524
Conversation
There was a problem hiding this comment.
Code Review
This pull request refines the handling of replicated duplicates and retry behavior within transactions, specifically addressing how committed identity is determined before audit I/O. It introduces tracking of the specific transaction handle (committedOn) and retry round (committedRound) for each write operation. This ensures that sibling writes to the same key are only considered as the commit base if they were saved in the current retry round. Additionally, it improves audit walk validation on retries by requiring known committed-origin provenance (walkOriginKnown) to prevent treating orphaned, uncommitted audit entries as proof of a committed duplicate. Extensive unit tests have been added to verify these behaviors under various conflict and retry scenarios. I have no feedback to provide as there are no review comments.
⊙ Problem
This brings #3453 to v5.3. On RocksDB, a replicated write that retries after a commit conflict skips every audit duplicate check. If another delivery already committed, the retry applies it again and a CRDT
addcounts twice: under a newer write, beside an out-of-order sibling ref, or on the replay after an open read snapshot.🤔 Merge to v5.3 before main?
Yes, as you asked. The port is #3453 as of
723f4ff, before main's #3510, which v5.3 does not have. #3453 itself now carries a merge of #3510.💡 Solution
Ported with v5.3's single log key: main's
receivedLogKeyandappendedLogKeyboth becometxnLogKey.🤔 Keep the numeric origin compare on v5.3?
Yes. #3453 dropped it when it merged #3510, where a per-handle minted key makes it redundant. v5.3 has no minted keys, so it still keeps two unmapped origins at one version apart (compare, test).
⚖️ Alternatives
🔧 Changes
resources/Table.ts:retryBaseIsCommittedseedswalkOriginKnown, carried throughpreviousVersionlinks and sibling refs; the identity skip and equal-version tie need it on a retry.hasSavedSameKeySiblingcounts a same-key sibling only if it staged in the same handle and retry round. ThestagedOwnAuditEntrycomment holds the rationale.resources/DatabaseTransaction.ts: writes record the handle and retry round they staged in; the replay clears the audit flags for writes on a non-durable abandoned handle.resources/DESIGN.md: keeps v5.3's text; the duplicate-identity bullet gains the retry rules, and the durable-log note says an abort publishes a readable orphan.✅ Verification
replicatedRetryDuplicate.test.jsis byte-identical to Stop retried replicated writes from re-applying a duplicate that already committed #3453 at723f4ff(same-key batch, terminal-abort orphan). With v5.3's originalTable.tsandDatabaseTransaction.ts, 6 of its cases fail; with this branch, all pass.replicatedRetryDuplicate+relayedHeadTieDuplicate: 45 passing.test:unit:resources: 4170 passing, 0 failing.Review-Attentiondecision list also carries slugs from a first review round that ran againstmainby mistake; that round reviewed none of this diff.identityBasealready loops the same chain; on a retry this calls it once more per write, the same order. N is the writes to one key in one transaction, normally 1–3.Framing-Verdict: better-alternative-exists (b55f8f526ef5)
Refs #3361
🤖 Generated by Claude Code (Claude Opus 5.5); posted via @kriszyp.
Release target: v5.3 — cherry-pick of #3453 before #3510
Related PRs: #3453 overlaps (source), #3478 overlaps (merged; the v5.3 base this extends), #3510 overlaps (main-only; why this ports 723f4ff), #3476 overlaps (merged on main; ported in #3478), #3499 overlaps (merged on main; ported in #3478), 9 others independent
Complexity: complicated
Review-Coverage: authored=codex; ran=cursor-composer,gemini; declined=claude,cursor-grok,muse,domain; rounds=2; full=1 @ 94d6143
Review-Attention: deep ~470m (critical: DatabaseTransaction.ts, Table.ts; decisions: do-less-alternative, ambiguous-chain-policy, native-root-cause, ambiguous-retry-provenance, logged-commit-liveness, portable-bundle, restore-lock-fallback, named-process-lifetime, archive-capabilities; raised: degraded review, earlier round at this SHA) @ 94d6143