Follow-up from #153 (comment).
If a PgDataSource points at the same database that holds the dbos schema, transaction_on still runs the full two-commit protocol (witness row + separate checkpoint commit) even though one commit could cover both — that's what ctx.transaction does. Go shortcuts this case (sameAsSystemDB).
The usual answer "just use ctx.transaction then" is incomplete: its Tx/Param API only binds six primitive types, so jsonb, uuid, arrays, timestamps, custom enums etc. are out of reach. A same-DB user with rich Postgres types currently has to choose between the limited type surface (one commit) and the native connection (two commits). The fast path would give them both.
Proposed shape: don't detect sameness — sqlx pools have no identity comparison, and comparing connect options is a heuristic where a wrong "same" silently breaks atomicity. Instead let the engine hand out a datasource built from its own pool, e.g. engine.system_datasource() -> PgDataSource, so sameness is guaranteed by construction. transaction_on with such a datasource takes a single-commit path: body on the native connection, operation_outputs checkpoint inserted in the same transaction, no witness row.
Open questions:
- where the checkpoint SQL lives for this path (the provider owns it today via
run_transaction_step; the fast path needs it on a caller-supplied connection)
- SQLite: same idea applies, same shape
- whether an explicitly-constructed
PgDataSource on the same DB should also opt in via a flag, or only the engine-handed one gets the fast path (lean: only by construction, keep it un-guessable)
Follow-up from #153 (comment).
If a
PgDataSourcepoints at the same database that holds thedbosschema,transaction_onstill runs the full two-commit protocol (witness row + separate checkpoint commit) even though one commit could cover both — that's whatctx.transactiondoes. Go shortcuts this case (sameAsSystemDB).The usual answer "just use
ctx.transactionthen" is incomplete: itsTx/ParamAPI only binds six primitive types, so jsonb, uuid, arrays, timestamps, custom enums etc. are out of reach. A same-DB user with rich Postgres types currently has to choose between the limited type surface (one commit) and the native connection (two commits). The fast path would give them both.Proposed shape: don't detect sameness — sqlx pools have no identity comparison, and comparing connect options is a heuristic where a wrong "same" silently breaks atomicity. Instead let the engine hand out a datasource built from its own pool, e.g.
engine.system_datasource() -> PgDataSource, so sameness is guaranteed by construction.transaction_onwith such a datasource takes a single-commit path: body on the native connection,operation_outputscheckpoint inserted in the same transaction, no witness row.Open questions:
run_transaction_step; the fast path needs it on a caller-supplied connection)PgDataSourceon the same DB should also opt in via a flag, or only the engine-handed one gets the fast path (lean: only by construction, keep it un-guessable)