Skip to content

AbstractReactiveTransactionManager throws IllegalStateException when rollback fails after commit attempt #34595

@SledgeHammer01

Description

@SledgeHammer01

Hi,

I'm working on a Spring / Hibernate Reactive integration since r2dbc isn't very useful at the moment without ORM support. My integration does use Mutiny / Vert.x under the covers due to that being a Hibernate Reactive thing, but that's irrelevant for this issue.

It's pretty much done and working, but during building out my unit tests, I ran across a bug in AbstractReactiveTransactionManager error handling that also affects R2dbcTransactionManager.

Scenario 1 "happy path" -- works as expected

doBegin() ok
do work ok
doCommit() ok

Scenario 2 "fails in 'work'" -- works as expected, exception bubbles up to controller

doBegin() ok
do work fails
doCommit() is NOT called
doRollback() IS called and is ok

Scenario 3 "fails in doCommit()" -- works as expected, exception bubbled up to controller

covered here: https://github.com/spring-projects/spring-framework/blob/main/spring-r2dbc/src/test/java/org/springframework/r2dbc/connection/R2dbcTransactionManagerTests.java#L223

doBegin() ok
do work ok
doCommit() fails
doRollback() IS called and is ok

Scenario 4 "fails in doCommit() AND doRollback()" -- doesn't work, wrong exception IllegalStateException gets bubbled up

doBegin() ok
do work ok
doCommit() fails
doRollback() fails

This scenario causes the code to end up here:

https://github.com/spring-projects/spring-framework/blob/main/spring-tx/src/main/java/org/springframework/transaction/reactive/AbstractReactiveTransactionManager.java#L619

and eventually we get an exception here when completionStatus == 2. This occurs because the syncs have already been cleared and TransactionSynchronizationManager::getSynchronizations() expects the syncs to still be there or it throws an exception.

https://github.com/spring-projects/spring-framework/blob/main/spring-tx/src/main/java/org/springframework/transaction/reactive/TransactionSynchronizationManager.java#L229

We get the incorrect IllegalStateException bubbling up to the controller.

Seems like maybe the intention was to cover this failure in one of these tests? But neither really cover both the commit and rollback failing:

https://github.com/spring-projects/spring-framework/blob/main/spring-r2dbc/src/test/java/org/springframework/r2dbc/connection/R2dbcTransactionManagerTests.java#L273-L316

EDIT: As a test hack, I used AspectJ to bypass AbstractReactiveTransactionManager::triggerAfterCompletion() and that lets the correct exception bubble up.

I'm thinking, in AbstractReactiveTransactionManager::triggerAfterCompletion() you need to add another check for completionStatus != 2?

Activity

added
in: dataIssues in data modules (jdbc, orm, oxm, tx)
on Mar 15, 2025
self-assigned this
on Mar 18, 2025
changed the title [-]Bug in AbstractReactiveTransactionManager?[/-] [+]AbstractReactiveTransactionManager throws IllegalStateException when rollback fails after commit attempt[/+] on Mar 19, 2025
added and removed on Mar 19, 2025
added this to the 6.2.5 milestone on Mar 19, 2025
added
status: backportedAn issue that has been backported to maintenance branches
and removed
for: backport-to-6.1.xMarks an issue as a candidate for backport to 6.1.x
on Mar 19, 2025
added a commit that references this issue on Mar 19, 2025
cc986cd
added a commit that references this issue on Mar 19, 2025
8c494e5
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

in: dataIssues in data modules (jdbc, orm, oxm, tx)status: backportedAn issue that has been backported to maintenance branchestype: bugA general bug

Type

No type

Projects

No projects

Relationships

None yet

    Development

    No branches or pull requests

      Participants

      @jhoeller@spring-projects-issues@SledgeHammer01

      Issue actions

        AbstractReactiveTransactionManager throws IllegalStateException when rollback fails after commit attempt · Issue #34595 · spring-projects/spring-framework