[JAVA] Customizer for Platform Transaction Manager added from Spring Boot 1.5

When Spring Boot is used, Bean definition of PlatformTransactionManager interface implementation class (DataSourceTransactionManager, JpaTransactionManager, JtaTransactionManager, etc ...) corresponding to the usage technology is automatically performed. Can it be used as default? It's a bit subtle, and I think there are some parameters that should be customized. That's it ... This time, I will introduce how to customize PlatformTransactionManager on Spring Boot.

Up to Spring Boot 1.4?

Until Spring Boot 1.4, if you wanted to customize the PlatformTransactionManager, you had to do one of the following:

@Bean
PlatformTransactionManager transactionManager(DataSource dataSource) {
	DataSourceTransactionManager transactionManager = new DataSourceTransactionManager(dataSource);
	transactionManager.setDefaultTimeout(30);
	transactionManager.setRollbackOnCommitFailure(true);
	// ...
	return transactionManager;
}
@Autowired
void configureTransactionManager(AbstractPlatformTransactionManager transactionManager) { //Beans automatically set by Spring Boot are injected and customized
	transactionManager.setDefaultTimeout(30);
	transactionManager.setRollbackOnCommitFailure(true);
	// ...
}

From Spring Boot 1.5 (scheduled to be released at the end of January)?

In addition to the above method, from Spring Boot 1.5, it will be possible to customize by registering the Bean of the implementation class of ʻorg.springframework.boot.autoconfigure.transaction.PlatformTransactionManagerCustomizer` in the DI container.

Excerpt from PlatformTransactionManagerCustomizer


public interface PlatformTransactionManagerCustomizer<T extends PlatformTransactionManager> {
	void customize(T transactionManager);
}

I think this mechanism is useful when you want to share customization logic among multiple applications.

Embedded implementation of PlatformTransactionManagerCustomizer

Actually ... Spring Boot provides a built-in class that implements the PlatformTransactionManagerCustomizer interface. The built-in implementation provided by Spring Boot allows you to customize the values of the following properties defined in ʻAbstractPlatformTransactionManager`. (gh-7561)

src/main/resources/application.properties


spring.transaction.default-timeout=30
spring.transaction.rollback-on-commit-failure=true

Note:

Regarding the handling of Spring transaction timeout value, "[MyBatis-Spring transaction timeout value is linked from Spring 1.3 !! (How is Spring transaction timeout value used?)](Http: // qiita. com / kazuki43zoo / items / 1ac208a49c1d6ceeb0b8 # spring% E3% 81% AE% E3% 83% 88% E3% 83% A9% E3% 83% B3% E3% 82% B6% E3% 82% AF% E3% 82% B7% E3% 83% A7% E3% 83% B3% E3% 82% BF% E3% 82% A4% E3% 83% A0% E3% 82% A2% E3% 82% A6% E3% 83% 88% E5% 80% A4% E3% 81% A3% E3% 81% A6% E3% 81% A9% E3% 81% 86% E4% BD% BF% E3% 82% 8F% E3% 82% 8C% E3% For the necessity of "82% 8B% E3% 81% AE% E3% 81% 8B)" and "flag for whether to perform rollback processing when an error occurs at commit time", "Spring DataSource TransactionManager If you use it, it may be committed in case of an error !? ".

How to create and customize an implementation class for PlatformTransactionManagerCustomizer

If you want to share your customization logic with multiple applications, it's a good idea to create and customize an implementation class for PlatformTransactionManagerCustomizer. (Imagine providing it as if it were a common library)

@Component
public class MyPlatformTransactionManagerCustomizer
		implements PlatformTransactionManagerCustomizer<AbstractPlatformTransactionManager> {
	@Override
	public void customize(AbstractPlatformTransactionManager transactionManager) {
		// ...Implement customization logic
	}
}

Note:

The customize method is called only when the PlatformTransactionManager generated by Spring Boot can be assigned to the type specified in the generics of the PlatformTransactionManagerCustomizer.

How to customize using a Lambda expression (Java SE 8+)

For application-specific customizations, you can also ad hoc implement the customize method of PlatformTransactionManagerCustomizer using a Java SE 8 supported Lambda expression without creating a class like the one above.

@Bean
PlatformTransactionManagerCustomizer<AbstractPlatformTransactionManager> transactionManagerCustomizer() {
	return transactionManager -> {
		// ...Implement customization logic
	};
}

~~Warning:~~

~~ If you use a Lambda expression ... The call control of the customize method by the type specified in the generics of PlatformTransactionManagerCustomizer does not work (= It is considered that PlatformTransactionManager is specified in the generics). ...). ~~ ~~ Therefore, if the PlatformTransactionManager generated by Spring Boot cannot be assigned to the type specified in the generics ...CalssCastException will occur, so be careful! !! ~~

** 12/30 15:40 added **

If a ClassCastException occurs, it will be ignored, so it will behave the same as when the class was created! !! !!

Application order of PlatformTransactionManagerCustomizer

Multiple PlatformTransactionManagerCustomizers can be applied, including the built-in Spring Boot implementation (TransactionProperties). The behavior when multiple PlatformTransactionManagerCustomizers are registered in the DI container is undefined by default. If you want to control the order ...

It can be achieved by doing this, but it seems that it cannot be done after the built-in implementation of Spring Boot (TransactionProperties). (At least ... I couldn't do it after the embedded implementation in my environment, but I don't think it's a problem.)

Summary

Although it has not been released yet, starting with Spring Boot 1.5, an interface (PlatformTransactionManagerCustomizer) that supports customizing PlatformTransactionManager has been added ~

That means ...

The following properties, which are likely to be customized frequently, can now be customized with ʻapplication.properties (or ʻapplication.yml) ~

I introduced that.

Spring Boot 1.5 is scheduled to be released in RC1 at the beginning of the year and the official version at the end of January. When RC1 comes out, I'll check the changes from Spring Boot 1.4 (I think).

at the end

I think this entry is probably the end of this year's Qiita. I'm thinking of posting as I like next year, so I hope it helps everyone a little. (Please comment if there is something strange or if you want to do more like this !!)

Well, there are only two days left this year ... Have a nice year ~: see_no_evil :: hear_no_evil:: speak_no_evil:

Recommended Posts

Customizer for Platform Transaction Manager added from Spring Boot 1.5
Try Spring Boot from 0 to 100.
Spring Boot for annotation learning
Spring Boot for the first time
Frequent annotations for Spring Boot tests
Google Cloud Platform with Spring Boot 2.0.0
Use DBUnit for Spring Boot test
Upgrade spring boot from 1.5 series to 2.0 series
Spring Boot starting from zero Part 2
Spring Boot starting from zero Part 1
Story when moving from Spring Boot 1.5 to 2.1
Changes when migrating from Spring Boot 1.5 to Spring Boot 2.0
WebMvcConfigurer Memorandum of Understanding for Spring Boot 2.0 (Spring 5)
Changes when migrating from Spring Boot 2.0 to Spring Boot 2.2
Sample code for DB control by declarative transaction in Spring Boot + Spring Data JPA
Book introduction: Spring Boot Recommended reference book for beginners!
Annotation notes when writing tests for Spring Boot
◆ Get API created by Spring Boot from React
From building an AWS cloud environment to deploying a Spring Boot app (for beginners)