spring-projects / spring-projects/spring-framework
Kotlin: R2DBC pool leaks connections on request cancellation
Nobody has claimed this yet.
- 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
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- 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