Add df.start_autonomous() for autonomous-transaction semantics#285
Open
pinodeca wants to merge 1 commit into
Open
Add df.start_autonomous() for autonomous-transaction semantics#285pinodeca wants to merge 1 commit into
pinodeca wants to merge 1 commit into
Conversation
Adds df.start_autonomous(), the PostgreSQL equivalent of Oracle's PRAGMA AUTONOMOUS_TRANSACTION. It persists and enqueues a durable function on a separate PostgreSQL session, so it commits independently and survives a rollback of the caller's transaction. Ordinary df.start() is unchanged and still participates in the caller's transaction. - src/dsl.rs: new df.start_autonomous(fut, label, database) pg_extern - src/client.rs: start_autonomous() loopback helper (+ note on a future alternative implementation using a store-function-graph activity) - sql/pg_durable--0.2.3--0.2.4.sql: additive CREATE FUNCTION (new C symbol; backward compatible with all prior schemas in the provider line) - docs/upgrade-testing.md, USER_GUIDE.md, CHANGELOG.md: documentation - tests/e2e/sql/54_autonomous_transaction.sql: proves survival across caller rollback, and that default df.start() rolls back with the caller
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.
Summary
Adds
df.start_autonomous()— the PostgreSQL equivalent of Oracle'sPRAGMA AUTONOMOUS_TRANSACTION. It starts a durable function that commits independently and survives a rollback of the caller's transaction. Ordinarydf.start()is unchanged and still participates in the caller's transaction.This closes the specific gap raised when comparing pg_durable to
pg_background: the "must persist even if the parent rolls back" requirement (audit trails, error logging, etc.). Everything else pg_durable already runs autonomously once the caller commits — this adds the rollback-survival case.How it works
df.start_autonomous()opens a fresh loopback connection authenticated as the calling role and runs the ordinarydf.start(...)there. Because each statement runs in autocommit mode, that innerdf.startcommits in its own transaction the moment it returns — regardless of what the outer caller later does. This is the same "separate backend" techniquepg_backgrounduses, but it reuses pg_durable's existing graph construction and duroxide enqueue path unchanged, and it avoids the orphaned-orchestration race that the default path has when a caller rolls back afterdf.start().df.start_autonomous()runs under the caller's identity and privileges (same RLS scope), and takes the same arguments asdf.start()(fut, optionallabel, optionaldatabase).Backward compatibility (upgrade)
Folded into the unreleased 0.2.4 (latest shipped tag is v0.2.3), so no new version was cut.
start_autonomous_wrapper). No existing function or symbol changes.0.2.3 → 0.2.4upgrade script'sCREATE FUNCTIONis the pgrx-generated fresh-install DDL copied verbatim, so upgrade and fresh install produce identical catalogs..soruns correctly against all previous schemas in the provider line (0.2.2, 0.2.3) —df.start()keeps binding to the unchangedstart_wrapper; an un-upgraded schema simply doesn't exposedf.start_autonomousyet.Future exploration (please weigh in)
There's a note in
src/client.rsproposing a cleaner alternative to opening a second client connection just to rundf.startin a new backend:That would remove the extra backend connection entirely and collapse the current dual write (graph in the caller's txn, enqueue out-of-band) into a single durable source of truth, eliminating the orphaned-orchestration race for good. Worth evaluating the trade-offs (payload size limits for large graphs, where identity/privilege validation happens, and how ordinary non-autonomous
df.start()would share the path).Testing
tests/e2e/sql/54_autonomous_transaction.sqlproves (a)df.start_autonomous()survives a callerROLLBACKand persists its work, and (b) defaultdf.start()rolls back with the caller../scripts/test-unit.sh— 194 passed./scripts/test-e2e-local.sh 54_autonomous— passed./scripts/test-upgrade.sh— all passed (Scenario A / B1 / B2)cargo fmt --check+cargo clippy— clean