Skip to content

Conversation

@artembilan
Copy link
Member

Fixes #3733

The @Transactional resolves a primary TransactionManager bean
from the application context which might not be sufficient for all
the use-case.

To make it work with the custom (or specific) TransactionManager
we have to extend a DefaultLockRepository and override all those
@Transactional method

  • Change the logic of the DefaultLockRepository from @Transactional
    to the TransactionTemplate and use provided TransactionManager
    or resolve one from the application context
  • Adjust tests to use explicit TransactionManager and call
    afterSingletonsInstantiated() to initialize a default TransactionTemplate
  • Mention the change in the docs

Fixes spring-projects#3733

The `@Transactional` resolves a primary `TransactionManager` bean
from the application context which might not be sufficient for all
the use-case.

To make it work with the custom (or specific) `TransactionManager`
we have to extend a `DefaultLockRepository` and override all those
`@Transactional` method

* Change the logic of the `DefaultLockRepository` from `@Transactional`
to the `TransactionTemplate` and use provided `TransactionManager`
or resolve one from the application context
* Adjust tests to use explicit `TransactionManager` and call
`afterSingletonsInstantiated()` to initialize a default `TransactionTemplate`
* Mention the change in the docs
@Override
public void afterSingletonsInstantiated() {
if (this.transactionManager == null) {
this.transactionManager = this.applicationContext.getBean(PlatformTransactionManager.class);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe try/catch with a friendly message to indicate if there is not one unique TM in the context, the registry needs one to be passed in?

DefaultTransactionDefinition transactionDefinition =
new DefaultTransactionDefinition(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
transactionDefinition.setIsolationLevel(TransactionDefinition.ISOLATION_SERIALIZABLE);
return new TransactionTemplate(this.transactionManager, transactionDefinition)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can't we store this template in a field too?

}
DefaultTransactionDefinition transactionDefinition =
new DefaultTransactionDefinition(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
transactionDefinition.setIsolationLevel(TransactionDefinition.ISOLATION_SERIALIZABLE);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not a field?

* Add `BeanInitializationException` for no-unique `PlatformTransactionManager`
bean in the `afterSingletonsInstantiated()`
@garyrussell garyrussell merged commit 4b57363 into spring-projects:main Apr 12, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants