SimpleTransactionScope does not suspend and resume its scoped objects [SPR-14148] #18720
Comments
Juergen Hoeller commented The In other words, why is synchronization active when no actual transaction is active? Are you possibly operating within a |
Maciej Miklas commented I've created a simple test case:
Now edit |
Juergen Hoeller commented In your test context, you're indeed running in a transaction synchronoization boundary without an actual transaction active. The following assertion added to your
The root of the problem is that we're not suspending and resuming the transaction-bound objects in such a scenario. A nested actual transaction should not only suspend the cleanup synchronization but also unbind the corresponding transaction-scoped objects and rebind them on completion, for the outer transaction synchronization boundary to pick them up again... analogous to how we handle transactional resources. I've fixed this for 4.3 RC2 and 4.2.6 now. Feel free to give the upcoming |
Maciej Miklas commented Thank you! |
Maciej Miklas opened SPR-14148 and commented
The idea is to define a bean in transaction scope, so that each transaction can use fresh instance of such bean.
However it's possible to call methods on such bean outside transaction and it's causing side effects.
Try following test case:
Point 4) will not behave as expected. Only one instance of transaction scoped bean will be created and it will be reused between following transactions.
The problem is, that we are calling method on our bean before transaction starts.
SimpleTransactionScope
registersCleanupSynchronization
on current thread. Now we are starting transaction and trying to access our bean. The problem it, thatAbstractPlatformTransactionManager
suspends current transaction, well there is none, but it suspends all synchronizers registered byTransactionSynchronizationManager#registerSynchronization(...).
Once the transaction is finished the method
SimpleTransactionScope$CleanupSynchronization#afterCompletion
will not be executed, because synchronizer is suspended.Simple solution to this problem would be adding assert to
SimpleTransactionScope#get(...)
I think, that using transaction scoped bean outside transaction should not be allowed, because it's behavior is undefined.
Affects: 4.2.5
The text was updated successfully, but these errors were encountered: