Skip to content

adapter: buffer a transaction's blind read-then-write until commit - #37924

Open
aljoscha wants to merge 1 commit into
aljoscha/occ-06-occ-pathfrom
aljoscha/occ-07-transactions-and-vars
Open

adapter: buffer a transaction's blind read-then-write until commit#37924
aljoscha wants to merge 1 commit into
aljoscha/occ-06-occ-pathfrom
aljoscha/occ-07-transactions-and-vars

Conversation

@aljoscha

@aljoscha aljoscha commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

Motivation

Part 7 of 7 in a stack that moves DELETE, UPDATE and INSERT ... SELECT
off the coordinator onto the session task, using optimistic concurrency
control. Design doc:
20260210_incremental_occ_read_then_write.md
(lands in part 6).

Part 6 refuses a read-then-write inside a multi-statement transaction, because
a write that commits immediately cannot be rolled back at transaction end.
That is the right answer only for a write that reads persisted state.

Closes SQL-593

Description

A write whose selection reads nothing produces diffs that are valid at any
timestamp, so it can be buffered as a session write op and land with the rest
of the transaction, which is what a constant INSERT already does.

Two predicates decide this and they have to agree. Before planning, a
syntactic one on depends_on() refuses a read-dependent write while refusing
is still possible. During execution the subscribe answers the same question
dynamically, and the loop's Committed arm asserts it has no write timestamp
to apply inside a transaction, which is that disagreement made observable. It
is a soft assertion because the write is already durable by then.

Separately: max_concurrent_occ_writes is sampled once at startup, so ALTER SYSTEM SET on it silently did nothing. The statement is still accepted, and
now warns that the change takes effect when environmentd restarts. RESET ALL
names every parameter rather than one, so it compares values instead of names.
The parameter also gets a domain constraint of at least 1, since zero permits
would leave every read-then-write waiting out its statement_timeout.

Verification

Tests for a non-constant INSERT in a transaction being buffered and
committing with the transaction, for a read-dependent write in a transaction
being refused, for a read-only transaction, and for the startup-only variable
warning on SET, RESET and RESET ALL.

@linear-code

linear-code Bot commented Jul 29, 2026

Copy link
Copy Markdown

SQL-593

@aljoscha
aljoscha force-pushed the aljoscha/occ-07-transactions-and-vars branch from cf8e804 to 143170a Compare July 29, 2026 12:19
@aljoscha
aljoscha force-pushed the aljoscha/occ-07-transactions-and-vars branch from 143170a to cc74c44 Compare July 29, 2026 13:25
@aljoscha
aljoscha force-pushed the aljoscha/occ-07-transactions-and-vars branch 2 times, most recently from 27be3b3 to af343a1 Compare July 29, 2026 15:26
@aljoscha
aljoscha force-pushed the aljoscha/occ-07-transactions-and-vars branch from af343a1 to 8a514a6 Compare July 29, 2026 15:51
@aljoscha
aljoscha force-pushed the aljoscha/occ-07-transactions-and-vars branch from 8a514a6 to a741eb6 Compare July 30, 2026 06:02
@aljoscha
aljoscha force-pushed the aljoscha/occ-07-transactions-and-vars branch from a741eb6 to ed20ee4 Compare July 30, 2026 06:24
@aljoscha
aljoscha force-pushed the aljoscha/occ-07-transactions-and-vars branch 2 times, most recently from e1ac18d to ae8eeca Compare July 30, 2026 07:04
@aljoscha
aljoscha force-pushed the aljoscha/occ-07-transactions-and-vars branch 2 times, most recently from 0766855 to d34e32f Compare July 30, 2026 08:10
@aljoscha
aljoscha force-pushed the aljoscha/occ-07-transactions-and-vars branch from d34e32f to df5a2de Compare July 30, 2026 08:34
@aljoscha
aljoscha force-pushed the aljoscha/occ-07-transactions-and-vars branch from df5a2de to ec6c426 Compare August 5, 2026 06:16
@aljoscha
aljoscha requested a review from a team as a code owner August 5, 2026 06:16
@aljoscha
aljoscha force-pushed the aljoscha/occ-07-transactions-and-vars branch from ec6c426 to 022b928 Compare August 5, 2026 12:13
A read-then-write inside a multi-statement transaction was refused
outright, because a write that commits immediately cannot be rolled back
at transaction end. That is the right answer only for a write that reads
persisted state. One whose selection reads nothing produces diffs that are
valid at any timestamp, so it can be buffered as a session write op and
land with the rest of the transaction, which is what a constant INSERT
already does.

Two predicates decide it and they have to agree. Before planning, the
syntactic one on `depends_on()` refuses a read-dependent write while
refusing is still possible. During execution, the subscribe answers the
same question dynamically, and the loop's `Committed` arm asserts it has
no write timestamp to apply inside a transaction, which is that
disagreement made observable. It is a soft assertion because the write is
durable by then.

`max_concurrent_occ_writes` is sampled once at startup, so `ALTER SYSTEM
SET` on it silently did nothing. The statement is accepted and now warns
that the change takes effect when environmentd restarts. `RESET ALL` names
every parameter rather than one, so it compares values instead of names.
The test for the parameter's domain constraint lands here too, though the
constraint itself arrives with the path that reads the parameter.
@aljoscha
aljoscha force-pushed the aljoscha/occ-07-transactions-and-vars branch from 022b928 to 5368027 Compare August 5, 2026 13:05
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