fix(api): opt BulkReplace down to READ COMMITTED and stop blanket-500ing bulk metadata store errors (#783) - #801
Merged
Merged
Conversation
…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
3 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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