Skip to content

fix(api): opt BulkReplace down to READ COMMITTED and stop blanket-500ing bulk metadata store errors (#783) - #801

Merged
ericfitz merged 2 commits into
mainfrom
fix/783-bulkreplace-isolation
Aug 21, 2026
Merged

fix(api): opt BulkReplace down to READ COMMITTED and stop blanket-500ing bulk metadata store errors (#783)#801
ericfitz merged 2 commits into
mainfrom
fix/783-bulkreplace-isolation

Conversation

@ericfitz

Copy link
Copy Markdown
Owner

Back-to-back same-entity BulkReplace exhausted the retry wrapper with a
FALSE ORA-08177 under the #451 SERIALIZABLE default: the metadata blocks
(and the hot right-edge leaf blocks of its timestamp-leading indexes)
carry Oracle's default INITRANS 1, so the second transaction recycles the
first one's ITL slot and the rows become unprovable — time-independent,
so retries could not help, and two quick PUT saves failed. BulkReplace is
a pure DELETE-then-INSERT that reads nothing it acts upon, so opting it
down to READ COMMITTED (the codebase's first per-site opt-down via the
documented #449 escape hatch; maintainer-approved on #783) makes the
failure impossible while preserving last-writer-wins on both engines.
godror materializes the explicit level as ALTER SESSION on pooled
connections (verified). The INITRANS/index root-cause work stays on #783.

Riding along, from the oracle-db-admin re-review: the three bulk metadata
handlers mapped EVERY store error to a blanket 500, so a retry-exhausted
transient reached clients as an undocumented 500 (zero-500 violation) —
they now route through StoreErrorToRequestError (duplicate -> 409,
transient -> 503+Retry-After, constraint -> 400), and 409 is added to the
OpenAPI responses of all 11 bulk metadata PUT/PATCH operations for the
concurrent colliding-key case (documented-status-code policy).

The warm-call assertion in the Oracle integration test is tightened back
to require deterministic success.

oracle-db-admin verdict: APPROVED WITH NOTES (both comment corrections
folded in; handler fix landed here rather than filed).

Refs #783

ericfitz and others added 2 commits August 21, 2026 00:31
…ing bulk metadata store errors (#783)

Back-to-back same-entity BulkReplace exhausted the retry wrapper with a
FALSE ORA-08177 under the #451 SERIALIZABLE default: the metadata blocks
(and the hot right-edge leaf blocks of its timestamp-leading indexes)
carry Oracle's default INITRANS 1, so the second transaction recycles the
first one's ITL slot and the rows become unprovable — time-independent,
so retries could not help, and two quick PUT saves failed. BulkReplace is
a pure DELETE-then-INSERT that reads nothing it acts upon, so opting it
down to READ COMMITTED (the codebase's first per-site opt-down via the
documented #449 escape hatch; maintainer-approved on #783) makes the
failure impossible while preserving last-writer-wins on both engines.
godror materializes the explicit level as ALTER SESSION on pooled
connections (verified). The INITRANS/index root-cause work stays on #783.

Riding along, from the oracle-db-admin re-review: the three bulk metadata
handlers mapped EVERY store error to a blanket 500, so a retry-exhausted
transient reached clients as an undocumented 500 (zero-500 violation) —
they now route through StoreErrorToRequestError (duplicate -> 409,
transient -> 503+Retry-After, constraint -> 400), and 409 is added to the
OpenAPI responses of all 11 bulk metadata PUT/PATCH operations for the
concurrent colliding-key case (documented-status-code policy).

The warm-call assertion in the Oracle integration test is tightened back
to require deterministic success.

oracle-db-admin verdict: APPROVED WITH NOTES (both comment corrections
folded in; handler fix landed here rather than filed).

Refs #783

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MVKNHGpMb8a7tQB5CZPBWS
@ericfitz
ericfitz merged commit 50b0513 into main Aug 21, 2026
15 checks passed
@ericfitz
ericfitz deleted the fix/783-bulkreplace-isolation branch August 21, 2026 04:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant