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:
- register transaction scope
- define bean in this scope
- call method on this bean
- start transaction and use bean inside it.
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 registers CleanupSynchronization on current thread. Now we are starting transaction and trying to access our bean. The problem it, that AbstractPlatformTransactionManager suspends current transaction, well there is none, but it suspends all synchronizers registered by TransactionSynchronizationManager#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.