spring-projects / spring-projects/spring-framework

Kotlin: R2DBC pool leaks connections on request cancellation

Open
#35,774 2 comments 16 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

in: data status: waiting-for-triage theme: kotlin
Dominant language
Java
Stars
60.2k
Forks
38.8k
Avg merge
5d 2h
Merged PRs (30d)
27

Description

Hi

Affects: Spring Boot (3.5.7), Spring Framework (6.2.12), namely spring-r2dbc, i think

Made a simple reproducer with detailed explanation and steps. Please, find it here.

Shortly, in Kotlin Spring Boot Webflux application with data-r2dbc and postgresql driver,
When request is cancelled during query execution and cancellation caught to insert another entity within separate transaction (Via TransactionalOperator), the connection that were handling the query become leaked (within idle in transaction state with ClientRead wait_event and no longer gets leased by the ConnectionPool

With C such request-cancel operations, where C = spring.r2dbc.pool.max-size (10 by default), the service become unresponsive (infinite wait on pool to acquire connection).

Not sure if this is the right place since I wasn't able to repeat this behavior with Java, so it might be related to kotlinx-coroutines-reactor.

Starting from here due to error messages

2025-11-07T15:38:30.257+03:00  WARN 49567 --- [spring-cpool-leak] [ctor-http-nio-4] reactor.core.publisher.FluxUsingWhen     : Async resource cleanup failed after cancel

java.lang.IllegalStateException: Transaction synchronization is not active
	at org.springframework.transaction.reactive.TransactionSynchronizationManager.getSynchronizations(TransactionSynchronizationManager.java:233) ~[spring-tx-6.2.12.jar:6.2.12]
	at org.springframework.transaction.reactive.AbstractReactiveTransactionManager.triggerBeforeCompletion(AbstractReactiveTransactionManager.java:654) ~[spring-tx-6.2.12.jar:6.2.12]
	at org.springframework.transaction.reactive.AbstractReactiveTransactionManager.processRollback(AbstractReactiveTransactionManager.java:548) ~[spring-tx-6.2.12.jar:6.2.12]
	at org.springframework.transaction.reactive.AbstractReactiveTransactionManager.lambda$rollback$43(AbstractReactiveTransactionManager.java:535) ~[spring-tx-6.2.12.jar:6.2.12]
<reactor + kotlinx.coroutines stack>

That might suggest that there are some problems with R2dbcTransactionManager

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the linked reproducer and the cleanup path involving spring-r2dbc, R2dbcTransactionManager, TransactionSynchronizationManager.java, and AbstractReactiveTransactionManager.java. Inspect the FluxUsingWhen warning and cancellation stack, then compare the Kotlin and Java behavior. Done means cancelled requests no longer leave connections idle in transaction or exhaust the ConnectionPool.

Written by the indexing model from the issue text.

Assessment

Tech stack
kotlin, postgresql, spring, spring-boot
Domain
backend, database
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.