fix: Abort running R2DBC statement when transaction coroutine is cancelled - #2942
Open
Matthew de Detrich (mdedetrich) wants to merge 1 commit into
Open
Matthew de Detrich (mdedetrich) wants to merge 1 commit into
Matthew de Detrich (mdedetrich) wants to merge 1 commit into
Conversation
Matthew de Detrich (mdedetrich)
force-pushed
the
fix/r2dbc-cancel-running-statement
branch
2 times, most recently
from
September 30, 2026 19:46
842782d to
18a068d
Compare
Matthew de Detrich (mdedetrich)
force-pushed
the
fix/r2dbc-cancel-running-statement
branch
from
September 30, 2026 19:52
18a068d to
41f831a
Compare
This branch has not been deployed
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.
Description
Summary of the change: Cancelling a coroutine running an R2DBC transaction now aborts the in-flight statement on the database (PostgreSQL), instead of waiting for it to run to completion.
Detailed description:
Why: R2DBC drivers drain a cancelled subscription rather than aborting the query. Exposed's rollback and connection release then queue behind the still-running statement, so a cancelled coroutine only completes once the query finishes (e.g. a
pg_sleep(30)cancelled after 2s took ~28s to join). Exposed holds the executing connection internally but never used it to cancel.At work, I am doing batch jobs in long running transactions on Postgres and currently there isn't a way to cancel the underlying transaction if the batches get cancelled. It would be ideal to model this using coroutine cancellation so that if an Exposed transaction in a coroutine gets cancelled it also cancels the database transaction.
What:
R2dbcConnectionImpltracks whether a statement may still be executing.CancellationExceptionin a transaction block, a driver-specific cancel request is sent on the transaction's own connection before rollback.R2dbcDatabaseConfig.cancelRunningStatementOnCancellation(defaulttrue) to opt out.How:
InFlightStatementTrackerwraps statement result publishers; a statement counts as in flight from subscription until a terminal signal (which never arrives after a downstream cancel).io.r2dbc.spi.Wrapped(so pooled connections work) down toPostgresqlConnection, andcancelRequest()is called. The Postgres driver iscompileOnly, so this is guarded by a classpath check; other drivers are a no-op.Type of Change
Please mark the relevant options with an "X":
Updates/remove existing public API methods:
Affected databases:
Checklist