From 80eee6b30fe4604fba84a036d238896afe359d4d Mon Sep 17 00:00:00 2001 From: Kazuki Shimizu Date: Sat, 3 Dec 2016 18:49:15 +0900 Subject: [PATCH 1/2] Support spring transaction manager properties Add Spring TransactionManager properties to allow timeout and rollback settings to be configured. See gh-7561 --- .../batch/BasicBatchConfigurer.java | 22 ++++-- .../batch/BatchAutoConfiguration.java | 14 +++- .../neo4j/Neo4jDataAutoConfiguration.java | 13 ++- ...ceTransactionManagerAutoConfiguration.java | 10 ++- .../orm/jpa/JpaBaseConfiguration.java | 10 ++- .../transaction/TransactionProperties.java | 79 +++++++++++++++++++ .../jta/AtomikosJtaConfiguration.java | 12 ++- .../jta/BitronixJtaConfiguration.java | 12 ++- .../transaction/jta/JndiJtaConfiguration.java | 14 +++- .../jta/NarayanaJtaConfiguration.java | 12 ++- .../batch/BatchAutoConfigurationTests.java | 38 +++++++++ .../Neo4jDataAutoConfigurationTests.java | 12 +++ ...nsactionManagerAutoConfigurationTests.java | 14 ++++ .../HibernateJpaAutoConfigurationTests.java | 13 +++ .../jta/JtaAutoConfigurationTests.java | 26 ++++++ 15 files changed, 275 insertions(+), 26 deletions(-) create mode 100644 spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/transaction/TransactionProperties.java diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/batch/BasicBatchConfigurer.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/batch/BasicBatchConfigurer.java index 251601ba28..d8f07295fe 100644 --- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/batch/BasicBatchConfigurer.java +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/batch/BasicBatchConfigurer.java @@ -30,6 +30,7 @@ import org.springframework.batch.core.launch.JobLauncher; import org.springframework.batch.core.launch.support.SimpleJobLauncher; import org.springframework.batch.core.repository.JobRepository; import org.springframework.batch.core.repository.support.JobRepositoryFactoryBean; +import org.springframework.boot.autoconfigure.transaction.TransactionProperties; import org.springframework.jdbc.datasource.DataSourceTransactionManager; import org.springframework.orm.jpa.JpaTransactionManager; import org.springframework.transaction.PlatformTransactionManager; @@ -40,6 +41,7 @@ import org.springframework.util.StringUtils; * * @author Dave Syer * @author Andy Wilkinson + * @author Kazuki Shimizu */ public class BasicBatchConfigurer implements BatchConfigurer { @@ -47,6 +49,8 @@ public class BasicBatchConfigurer implements BatchConfigurer { private final BatchProperties properties; + private final TransactionProperties transactionProperties; + private final DataSource dataSource; private final EntityManagerFactory entityManagerFactory; @@ -62,21 +66,24 @@ public class BasicBatchConfigurer implements BatchConfigurer { /** * Create a new {@link BasicBatchConfigurer} instance. * @param properties the batch properties + * @param transactionProperties the transaction properties * @param dataSource the underlying data source */ - protected BasicBatchConfigurer(BatchProperties properties, DataSource dataSource) { - this(properties, dataSource, null); + protected BasicBatchConfigurer(BatchProperties properties, TransactionProperties transactionProperties, DataSource dataSource) { + this(properties, transactionProperties, dataSource, null); } /** * Create a new {@link BasicBatchConfigurer} instance. * @param properties the batch properties + * @param transactionProperties the transaction properties * @param dataSource the underlying data source * @param entityManagerFactory the entity manager factory (or {@code null}) */ - protected BasicBatchConfigurer(BatchProperties properties, DataSource dataSource, + protected BasicBatchConfigurer(BatchProperties properties, TransactionProperties transactionProperties, DataSource dataSource, EntityManagerFactory entityManagerFactory) { this.properties = properties; + this.transactionProperties = transactionProperties; this.entityManagerFactory = entityManagerFactory; this.dataSource = dataSource; } @@ -150,10 +157,15 @@ public class BasicBatchConfigurer implements BatchConfigurer { } protected PlatformTransactionManager createTransactionManager() { + PlatformTransactionManager txManager; if (this.entityManagerFactory != null) { - return new JpaTransactionManager(this.entityManagerFactory); + txManager = new JpaTransactionManager(this.entityManagerFactory); + } + else { + txManager = new DataSourceTransactionManager(this.dataSource); } - return new DataSourceTransactionManager(this.dataSource); + this.transactionProperties.applyTo(txManager); + return txManager; } } diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/batch/BatchAutoConfiguration.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/batch/BatchAutoConfiguration.java index cb9c3515c8..44eefb73f7 100644 --- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/batch/BatchAutoConfiguration.java +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/batch/BatchAutoConfiguration.java @@ -37,11 +37,13 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration; +import org.springframework.boot.autoconfigure.transaction.TransactionProperties; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.io.ResourceLoader; import org.springframework.jdbc.core.JdbcOperations; +import org.springframework.transaction.PlatformTransactionManager; import org.springframework.util.StringUtils; /** @@ -57,6 +59,7 @@ import org.springframework.util.StringUtils; * * @author Dave Syer * @author EddĂș MelĂ©ndez + * @author Kazuki Shimizu */ @Configuration @ConditionalOnClass({ JobLauncher.class, DataSource.class, JdbcOperations.class }) @@ -133,15 +136,18 @@ public class BatchAutoConfiguration { return factory; } - @ConditionalOnClass(name = "javax.persistence.EntityManagerFactory") + @EnableConfigurationProperties({BatchProperties.class, TransactionProperties.class}) + @ConditionalOnClass(value = PlatformTransactionManager.class, name = "javax.persistence.EntityManagerFactory") @ConditionalOnMissingBean(BatchConfigurer.class) @Configuration protected static class JpaBatchConfiguration { private final BatchProperties properties; + private final TransactionProperties transactionProperties; - protected JpaBatchConfiguration(BatchProperties properties) { + protected JpaBatchConfiguration(BatchProperties properties, TransactionProperties transactionProperties) { this.properties = properties; + this.transactionProperties = transactionProperties; } // The EntityManagerFactory may not be discoverable by type when this condition @@ -151,14 +157,14 @@ public class BatchAutoConfiguration { @ConditionalOnBean(name = "entityManagerFactory") public BasicBatchConfigurer jpaBatchConfigurer(DataSource dataSource, EntityManagerFactory entityManagerFactory) { - return new BasicBatchConfigurer(this.properties, dataSource, + return new BasicBatchConfigurer(this.properties, this.transactionProperties, dataSource, entityManagerFactory); } @Bean @ConditionalOnMissingBean(name = "entityManagerFactory") public BasicBatchConfigurer basicBatchConfigurer(DataSource dataSource) { - return new BasicBatchConfigurer(this.properties, dataSource); + return new BasicBatchConfigurer(this.properties, this.transactionProperties, dataSource); } } diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jDataAutoConfiguration.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jDataAutoConfiguration.java index e5743e2595..19bbc4004e 100644 --- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jDataAutoConfiguration.java +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jDataAutoConfiguration.java @@ -29,6 +29,7 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; import org.springframework.boot.autoconfigure.domain.EntityScanPackages; +import org.springframework.boot.autoconfigure.transaction.TransactionProperties; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Bean; @@ -48,12 +49,13 @@ import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter * @author Josh Long * @author Vince Bickers * @author Stephane Nicoll + * @author Kazuki Shimizu * @since 1.4.0 */ @Configuration -@ConditionalOnClass(SessionFactory.class) +@ConditionalOnClass({SessionFactory.class, PlatformTransactionManager.class}) @ConditionalOnMissingBean(SessionFactory.class) -@EnableConfigurationProperties(Neo4jProperties.class) +@EnableConfigurationProperties({Neo4jProperties.class, TransactionProperties.class}) @SuppressWarnings("deprecation") public class Neo4jDataAutoConfiguration { @@ -87,8 +89,11 @@ public class Neo4jDataAutoConfiguration { @Bean @ConditionalOnMissingBean(PlatformTransactionManager.class) - public Neo4jTransactionManager transactionManager(SessionFactory sessionFactory) { - return new Neo4jTransactionManager(sessionFactory); + public Neo4jTransactionManager transactionManager(SessionFactory sessionFactory, + TransactionProperties transactionProperties) { + Neo4jTransactionManager transactionManager = new Neo4jTransactionManager(sessionFactory); + transactionProperties.applyTo(transactionManager); + return transactionManager; } private String[] getPackagesToScan(ApplicationContext applicationContext) { diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/DataSourceTransactionManagerAutoConfiguration.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/DataSourceTransactionManagerAutoConfiguration.java index d5feaf1352..7632f16196 100644 --- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/DataSourceTransactionManagerAutoConfiguration.java +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/DataSourceTransactionManagerAutoConfiguration.java @@ -23,6 +23,8 @@ import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnSingleCandidate; +import org.springframework.boot.autoconfigure.transaction.TransactionProperties; +import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.Ordered; @@ -39,6 +41,7 @@ import org.springframework.transaction.annotation.EnableTransactionManagement; * @author Dave Syer * @author Stephane Nicoll * @author Andy Wilkinson + * @author Kazuki Shimizu */ @Configuration @ConditionalOnClass({ JdbcTemplate.class, PlatformTransactionManager.class }) @@ -47,6 +50,7 @@ public class DataSourceTransactionManagerAutoConfiguration { @Configuration @ConditionalOnSingleCandidate(DataSource.class) + @EnableConfigurationProperties(TransactionProperties.class) static class DataSourceTransactionManagerConfiguration { private final DataSource dataSource; @@ -57,8 +61,10 @@ public class DataSourceTransactionManagerAutoConfiguration { @Bean @ConditionalOnMissingBean(PlatformTransactionManager.class) - public DataSourceTransactionManager transactionManager() { - return new DataSourceTransactionManager(this.dataSource); + public DataSourceTransactionManager transactionManager(TransactionProperties transactionProperties) { + DataSourceTransactionManager transactionManager = new DataSourceTransactionManager(this.dataSource); + transactionProperties.applyTo(transactionManager); + return transactionManager; } } diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/orm/jpa/JpaBaseConfiguration.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/orm/jpa/JpaBaseConfiguration.java index 67d1ccbd96..a4d05fd6b8 100644 --- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/orm/jpa/JpaBaseConfiguration.java +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/orm/jpa/JpaBaseConfiguration.java @@ -34,6 +34,7 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; import org.springframework.boot.autoconfigure.domain.EntityScanPackages; +import org.springframework.boot.autoconfigure.transaction.TransactionProperties; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder; import org.springframework.context.annotation.Bean; @@ -59,8 +60,9 @@ import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter * @author Dave Syer * @author Oliver Gierke * @author Andy Wilkinson + * @author Kazuki Shimizu */ -@EnableConfigurationProperties(JpaProperties.class) +@EnableConfigurationProperties({JpaProperties.class, TransactionProperties.class}) @Import(DataSourceInitializedPublisher.Registrar.class) public abstract class JpaBaseConfiguration implements BeanFactoryAware { @@ -81,8 +83,10 @@ public abstract class JpaBaseConfiguration implements BeanFactoryAware { @Bean @ConditionalOnMissingBean(PlatformTransactionManager.class) - public PlatformTransactionManager transactionManager() { - return new JpaTransactionManager(); + public PlatformTransactionManager transactionManager(TransactionProperties transactionProperties) { + JpaTransactionManager transactionManager = new JpaTransactionManager(); + transactionProperties.applyTo(transactionManager); + return transactionManager; } @Bean diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/transaction/TransactionProperties.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/transaction/TransactionProperties.java new file mode 100644 index 0000000000..41a3499080 --- /dev/null +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/transaction/TransactionProperties.java @@ -0,0 +1,79 @@ +/* + * Copyright 2012-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.autoconfigure.transaction; + +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.transaction.PlatformTransactionManager; +import org.springframework.transaction.support.AbstractPlatformTransactionManager; + +/** + * External configuration properties for a {@link org.springframework.transaction.PlatformTransactionManager} created by + * Spring. All {@literal spring.transaction.} properties are also applied to the {@code PlatformTransactionManager}. + * + * @author Kazuki Shimizu + * @since 1.5.0 + */ +@ConfigurationProperties(prefix = "spring.transaction") +public class TransactionProperties { + + /** + * The default transaction timeout (sec). + */ + private Integer defaultTimeout; + + /** + * The indicating flag whether perform the rollback processing on commit failure (If perform rollback, set to the true). + */ + private Boolean rollbackOnCommitFailure; + + public Integer getDefaultTimeout() { + return this.defaultTimeout; + } + + public void setDefaultTimeout(Integer defaultTimeout) { + this.defaultTimeout = defaultTimeout; + } + + public Boolean getRollbackOnCommitFailure() { + return this.rollbackOnCommitFailure; + } + + public void setRollbackOnCommitFailure(Boolean rollbackOnCommitFailure) { + this.rollbackOnCommitFailure = rollbackOnCommitFailure; + } + + /** + * Apply all transaction custom properties to a specified {@link PlatformTransactionManager} instance. + * + * @param transactionManager the target transaction manager + * @see AbstractPlatformTransactionManager#setDefaultTimeout(int) + * @see AbstractPlatformTransactionManager#setRollbackOnCommitFailure(boolean) + */ + public void applyTo(PlatformTransactionManager transactionManager) { + if (transactionManager instanceof AbstractPlatformTransactionManager) { + AbstractPlatformTransactionManager abstractPlatformTransactionManager = + (AbstractPlatformTransactionManager) transactionManager; + if (this.defaultTimeout != null) { + abstractPlatformTransactionManager.setDefaultTimeout(this.defaultTimeout); + } + if (this.rollbackOnCommitFailure != null) { + abstractPlatformTransactionManager.setRollbackOnCommitFailure(this.rollbackOnCommitFailure); + } + } + } + +} diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/transaction/jta/AtomikosJtaConfiguration.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/transaction/jta/AtomikosJtaConfiguration.java index bde242ed0b..e5b6d7b37c 100644 --- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/transaction/jta/AtomikosJtaConfiguration.java +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/transaction/jta/AtomikosJtaConfiguration.java @@ -30,6 +30,7 @@ import com.atomikos.icatch.jta.UserTransactionManager; import org.springframework.boot.ApplicationHome; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.autoconfigure.transaction.TransactionProperties; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.boot.jta.XAConnectionFactoryWrapper; import org.springframework.boot.jta.XADataSourceWrapper; @@ -50,18 +51,21 @@ import org.springframework.util.StringUtils; * @author Phillip Webb * @author Andy Wilkinson * @author Stephane Nicoll + * @author Kazuki Shimizu * @since 1.2.0 */ @Configuration -@EnableConfigurationProperties(AtomikosProperties.class) +@EnableConfigurationProperties({AtomikosProperties.class, JtaProperties.class, TransactionProperties.class}) @ConditionalOnClass({ JtaTransactionManager.class, UserTransactionManager.class }) @ConditionalOnMissingBean(PlatformTransactionManager.class) class AtomikosJtaConfiguration { private final JtaProperties jtaProperties; + private final TransactionProperties transactionProperties; - AtomikosJtaConfiguration(JtaProperties jtaProperties) { + AtomikosJtaConfiguration(JtaProperties jtaProperties, TransactionProperties transactionProperties) { this.jtaProperties = jtaProperties; + this.transactionProperties = transactionProperties; } @Bean(initMethod = "init", destroyMethod = "shutdownForce") @@ -111,7 +115,9 @@ class AtomikosJtaConfiguration { @Bean public JtaTransactionManager transactionManager(UserTransaction userTransaction, TransactionManager transactionManager) { - return new JtaTransactionManager(userTransaction, transactionManager); + JtaTransactionManager jtaTransactionManager = new JtaTransactionManager(userTransaction, transactionManager); + this.transactionProperties.applyTo(jtaTransactionManager); + return jtaTransactionManager; } @Configuration diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/transaction/jta/BitronixJtaConfiguration.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/transaction/jta/BitronixJtaConfiguration.java index c10098ce14..efcb403b94 100644 --- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/transaction/jta/BitronixJtaConfiguration.java +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/transaction/jta/BitronixJtaConfiguration.java @@ -28,7 +28,9 @@ import bitronix.tm.jndi.BitronixContext; import org.springframework.boot.ApplicationHome; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.autoconfigure.transaction.TransactionProperties; import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.boot.jta.XAConnectionFactoryWrapper; import org.springframework.boot.jta.XADataSourceWrapper; import org.springframework.boot.jta.bitronix.BitronixDependentBeanFactoryPostProcessor; @@ -46,17 +48,21 @@ import org.springframework.util.StringUtils; * @author Josh Long * @author Phillip Webb * @author Andy Wilkinson + * @author Kazuki Shimizu * @since 1.2.0 */ @Configuration +@EnableConfigurationProperties({JtaProperties.class, TransactionProperties.class}) @ConditionalOnClass({ JtaTransactionManager.class, BitronixContext.class }) @ConditionalOnMissingBean(PlatformTransactionManager.class) class BitronixJtaConfiguration { private final JtaProperties jtaProperties; + private final TransactionProperties transactionProperties; - BitronixJtaConfiguration(JtaProperties jtaProperties) { + BitronixJtaConfiguration(JtaProperties jtaProperties, TransactionProperties transactionProperties) { this.jtaProperties = jtaProperties; + this.transactionProperties = transactionProperties; } @Bean @@ -105,7 +111,9 @@ class BitronixJtaConfiguration { @Bean public JtaTransactionManager transactionManager( TransactionManager transactionManager) { - return new JtaTransactionManager(transactionManager); + JtaTransactionManager jtaTransactionManager = new JtaTransactionManager(transactionManager); + this.transactionProperties.applyTo(jtaTransactionManager); + return jtaTransactionManager; } @ConditionalOnClass(Message.class) diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/transaction/jta/JndiJtaConfiguration.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/transaction/jta/JndiJtaConfiguration.java index 12f20dd39f..c35c62db5b 100644 --- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/transaction/jta/JndiJtaConfiguration.java +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/transaction/jta/JndiJtaConfiguration.java @@ -19,6 +19,8 @@ package org.springframework.boot.autoconfigure.transaction.jta; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnJndi; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.autoconfigure.transaction.TransactionProperties; +import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.transaction.PlatformTransactionManager; @@ -30,6 +32,7 @@ import org.springframework.transaction.jta.JtaTransactionManager; * * @author Phillip Webb * @author Stephane Nicoll + * @author Kazuki Shimizu * @since 1.2.0 */ @Configuration @@ -38,11 +41,20 @@ import org.springframework.transaction.jta.JtaTransactionManager; "java:comp/TransactionManager", "java:appserver/TransactionManager", "java:pm/TransactionManager", "java:/TransactionManager" }) @ConditionalOnMissingBean(PlatformTransactionManager.class) +@EnableConfigurationProperties(TransactionProperties.class) class JndiJtaConfiguration { + private final TransactionProperties transactionProperties; + + JndiJtaConfiguration(TransactionProperties transactionProperties) { + this.transactionProperties = transactionProperties; + } + @Bean public JtaTransactionManager transactionManager() { - return new JtaTransactionManagerFactoryBean().getObject(); + JtaTransactionManager transactionManager = new JtaTransactionManagerFactoryBean().getObject(); + this.transactionProperties.applyTo(transactionManager); + return transactionManager; } } diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/transaction/jta/NarayanaJtaConfiguration.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/transaction/jta/NarayanaJtaConfiguration.java index 31394d6ed9..99c98f7f8f 100644 --- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/transaction/jta/NarayanaJtaConfiguration.java +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/transaction/jta/NarayanaJtaConfiguration.java @@ -28,6 +28,8 @@ import org.jboss.tm.XAResourceRecoveryRegistry; import org.springframework.boot.ApplicationHome; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.autoconfigure.transaction.TransactionProperties; +import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.boot.jta.XAConnectionFactoryWrapper; import org.springframework.boot.jta.XADataSourceWrapper; import org.springframework.boot.jta.narayana.NarayanaBeanFactoryPostProcessor; @@ -47,18 +49,22 @@ import org.springframework.util.StringUtils; * JTA Configuration for Narayana. * * @author Gytis Trikleris + * @author Kazuki Shimizu * @since 1.4.0 */ @Configuration @ConditionalOnClass({ JtaTransactionManager.class, com.arjuna.ats.jta.UserTransaction.class, XAResourceRecoveryRegistry.class }) @ConditionalOnMissingBean(PlatformTransactionManager.class) +@EnableConfigurationProperties({JtaProperties.class, TransactionProperties.class}) public class NarayanaJtaConfiguration { private final JtaProperties jtaProperties; + private final TransactionProperties transactionProperties; - public NarayanaJtaConfiguration(JtaProperties jtaProperties) { + public NarayanaJtaConfiguration(JtaProperties jtaProperties, TransactionProperties transactionProperties) { this.jtaProperties = jtaProperties; + this.transactionProperties = transactionProperties; } @Bean @@ -116,7 +122,9 @@ public class NarayanaJtaConfiguration { @Bean public JtaTransactionManager transactionManager(UserTransaction userTransaction, TransactionManager transactionManager) { - return new JtaTransactionManager(userTransaction, transactionManager); + JtaTransactionManager jtaTransactionManager = new JtaTransactionManager(userTransaction, transactionManager); + this.transactionProperties.applyTo(jtaTransactionManager); + return jtaTransactionManager; } @Bean diff --git a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/batch/BatchAutoConfigurationTests.java b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/batch/BatchAutoConfigurationTests.java index c668df5019..e793ef3e44 100644 --- a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/batch/BatchAutoConfigurationTests.java +++ b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/batch/BatchAutoConfigurationTests.java @@ -58,6 +58,8 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.jdbc.BadSqlGrammarException; import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.jdbc.datasource.DataSourceTransactionManager; +import org.springframework.orm.jpa.JpaTransactionManager; import org.springframework.transaction.PlatformTransactionManager; import static org.assertj.core.api.Assertions.assertThat; @@ -267,6 +269,42 @@ public class BatchAutoConfigurationTests { .queryForList("select * from BATCH_JOB_EXECUTION"); } + @Test + public void testCustomizeJpaTransactionManagerUsingProperties() throws Exception { + this.context = new AnnotationConfigApplicationContext(); + EnvironmentTestUtils.addEnvironment(this.context, + "spring.transaction.default-timeout:30", + "spring.transaction.rollback-on-commit-failure:true"); + this.context.register(TestConfiguration.class, + EmbeddedDataSourceConfiguration.class, + HibernateJpaAutoConfiguration.class, BatchAutoConfiguration.class, + PropertyPlaceholderAutoConfiguration.class); + this.context.refresh(); + this.context.getBean(BatchConfigurer.class); + JpaTransactionManager transactionManager = JpaTransactionManager.class.cast( + this.context.getBean(BatchConfigurer.class).getTransactionManager()); + assertThat(transactionManager.getDefaultTimeout()).isEqualTo(30); + assertThat(transactionManager.isRollbackOnCommitFailure()).isTrue(); + } + + @Test + public void testCustomizeDataSourceTransactionManagerUsingProperties() throws Exception { + this.context = new AnnotationConfigApplicationContext(); + EnvironmentTestUtils.addEnvironment(this.context, + "spring.transaction.default-timeout:30", + "spring.transaction.rollback-on-commit-failure:true"); + this.context.register(TestConfiguration.class, + EmbeddedDataSourceConfiguration.class, + BatchAutoConfiguration.class, + PropertyPlaceholderAutoConfiguration.class); + this.context.refresh(); + this.context.getBean(BatchConfigurer.class); + DataSourceTransactionManager transactionManager = DataSourceTransactionManager.class.cast( + this.context.getBean(BatchConfigurer.class).getTransactionManager()); + assertThat(transactionManager.getDefaultTimeout()).isEqualTo(30); + assertThat(transactionManager.isRollbackOnCommitFailure()).isTrue(); + } + @Configuration protected static class EmptyConfiguration { diff --git a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jDataAutoConfigurationTests.java b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jDataAutoConfigurationTests.java index 25fc2b5662..49031a48bd 100644 --- a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jDataAutoConfigurationTests.java +++ b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jDataAutoConfigurationTests.java @@ -37,6 +37,7 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.neo4j.mapping.Neo4jMappingContext; import org.springframework.data.neo4j.template.Neo4jOperations; +import org.springframework.data.neo4j.transaction.Neo4jTransactionManager; import org.springframework.data.neo4j.web.support.OpenSessionInViewInterceptor; import org.springframework.web.context.support.AnnotationConfigWebApplicationContext; @@ -73,10 +74,21 @@ public class Neo4jDataAutoConfigurationTests { .hasSize(1); assertThat(this.context.getBeansOfType(SessionFactory.class)).hasSize(1); assertThat(this.context.getBeansOfType(Neo4jOperations.class)).hasSize(1); + assertThat(this.context.getBeansOfType(Neo4jTransactionManager.class)).hasSize(1); assertThat(this.context.getBeansOfType(OpenSessionInViewInterceptor.class)) .isEmpty(); } + @Test + public void customNeo4jTransactionManagerUsingProperties() { + load(null, + "spring.transaction.default-timeout=30", + "spring.transaction.rollback-on-commit-failure:true"); + Neo4jTransactionManager transactionManager = this.context.getBean(Neo4jTransactionManager.class); + assertThat(transactionManager.getDefaultTimeout()).isEqualTo(30); + assertThat(transactionManager.isRollbackOnCommitFailure()).isTrue(); + } + @Test public void customSessionFactory() { load(CustomSessionFactory.class); diff --git a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jdbc/DataSourceTransactionManagerAutoConfigurationTests.java b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jdbc/DataSourceTransactionManagerAutoConfigurationTests.java index 93b44a1414..70ea23679e 100644 --- a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jdbc/DataSourceTransactionManagerAutoConfigurationTests.java +++ b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jdbc/DataSourceTransactionManagerAutoConfigurationTests.java @@ -20,6 +20,7 @@ import javax.sql.DataSource; import org.junit.Test; +import org.springframework.boot.test.util.EnvironmentTestUtils; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -106,6 +107,19 @@ public class DataSourceTransactionManagerAutoConfigurationTests { .isNotNull(); } + @Test + public void testCustomizeDataSourceTransactionManagerUsingProperties() throws Exception { + EnvironmentTestUtils.addEnvironment(this.context, + "spring.transaction.default-timeout:30", + "spring.transaction.rollback-on-commit-failure:true"); + this.context.register(EmbeddedDataSourceConfiguration.class, + DataSourceTransactionManagerAutoConfiguration.class); + this.context.refresh(); + DataSourceTransactionManager transactionManager = this.context.getBean(DataSourceTransactionManager.class); + assertThat(transactionManager.getDefaultTimeout()).isEqualTo(30); + assertThat(transactionManager.isRollbackOnCommitFailure()).isTrue(); + } + @EnableTransactionManagement protected static class SwitchTransactionsOn { diff --git a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaAutoConfigurationTests.java b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaAutoConfigurationTests.java index 1c2b4798ac..ff67fcf246 100644 --- a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaAutoConfigurationTests.java +++ b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaAutoConfigurationTests.java @@ -38,6 +38,7 @@ import org.springframework.boot.autoconfigure.transaction.jta.JtaAutoConfigurati import org.springframework.boot.orm.jpa.hibernate.SpringJtaPlatform; import org.springframework.boot.test.util.EnvironmentTestUtils; import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.orm.jpa.JpaTransactionManager; import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; import static org.assertj.core.api.Assertions.assertThat; @@ -171,6 +172,18 @@ public class HibernateJpaAutoConfigurationTests .isEqualTo(TestJtaPlatform.class.getName()); } + @Test + public void testCustomJpaTransactionManagerUsingProperties() throws Exception { + EnvironmentTestUtils.addEnvironment(this.context, + "spring.transaction.default-timeout:30", + "spring.transaction.rollback-on-commit-failure:true"); + setupTestConfiguration(); + this.context.refresh(); + JpaTransactionManager transactionManager = context.getBean(JpaTransactionManager.class); + assertThat(transactionManager.getDefaultTimeout()).isEqualTo(30); + assertThat(transactionManager.isRollbackOnCommitFailure()).isTrue(); + } + public static class TestJtaPlatform implements JtaPlatform { @Override diff --git a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/transaction/jta/JtaAutoConfigurationTests.java b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/transaction/jta/JtaAutoConfigurationTests.java index f57b84e2fa..2193e59155 100644 --- a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/transaction/jta/JtaAutoConfigurationTests.java +++ b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/transaction/jta/JtaAutoConfigurationTests.java @@ -245,6 +245,32 @@ public class JtaAutoConfigurationTests { assertThat(dataSource.getMaxPoolSize()).isEqualTo(10); } + @Test + public void atomikosCustomizeJtaTransactionManagerUsingProperties() throws Exception { + this.context = new AnnotationConfigApplicationContext(); + EnvironmentTestUtils.addEnvironment(this.context, + "spring.transaction.default-timeout:30", + "spring.transaction.rollback-on-commit-failure:true"); + this.context.register(AtomikosJtaConfiguration.class); + this.context.refresh(); + JtaTransactionManager transactionManager = this.context.getBean(JtaTransactionManager.class); + assertThat(transactionManager.getDefaultTimeout()).isEqualTo(30); + assertThat(transactionManager.isRollbackOnCommitFailure()).isTrue(); + } + + @Test + public void bitronixCustomizeJtaTransactionManagerUsingProperties() throws Exception { + this.context = new AnnotationConfigApplicationContext(); + EnvironmentTestUtils.addEnvironment(this.context, + "spring.transaction.default-timeout:30", + "spring.transaction.rollback-on-commit-failure:true"); + this.context.register(BitronixJtaConfiguration.class); + this.context.refresh(); + JtaTransactionManager transactionManager = this.context.getBean(JtaTransactionManager.class); + assertThat(transactionManager.getDefaultTimeout()).isEqualTo(30); + assertThat(transactionManager.isRollbackOnCommitFailure()).isTrue(); + } + @Configuration @EnableConfigurationProperties(JtaProperties.class) public static class JtaPropertiesConfiguration { From 99e72664d9eda43c170d339ca7b5c5986f6b8a33 Mon Sep 17 00:00:00 2001 From: Phillip Webb Date: Tue, 20 Dec 2016 15:27:41 -0800 Subject: [PATCH 2/2] Polish spring transaction manager properties Polish and update contribution so that TransactionManager properties can be defined per technology, rather than globally. Closes gh-7561 --- .../batch/BasicBatchConfigurer.java | 28 +++++++--------- .../batch/BatchAutoConfiguration.java | 11 +++---- .../autoconfigure/batch/BatchProperties.java | 21 ++++++++---- .../neo4j/Neo4jDataAutoConfiguration.java | 12 +++---- .../data/neo4j/Neo4jProperties.java | 9 ++++++ .../jdbc/DataSourceProperties.java | 9 ++++++ ...ceTransactionManagerAutoConfiguration.java | 11 ++++--- .../orm/jpa/JpaBaseConfiguration.java | 7 ++-- .../autoconfigure/orm/jpa/JpaProperties.java | 8 +++++ .../transaction/TransactionProperties.java | 32 +++++++------------ .../jta/AtomikosJtaConfiguration.java | 12 +++---- .../jta/BitronixJtaConfiguration.java | 12 +++---- .../transaction/jta/JndiJtaConfiguration.java | 14 ++++---- .../transaction/jta/JtaProperties.java | 9 ++++++ .../jta/NarayanaJtaConfiguration.java | 12 +++---- .../batch/BatchAutoConfigurationTests.java | 20 ++++++------ .../Neo4jDataAutoConfigurationTests.java | 9 +++--- ...nsactionManagerAutoConfigurationTests.java | 10 +++--- .../HibernateJpaAutoConfigurationTests.java | 8 +++-- .../jta/JtaAutoConfigurationTests.java | 15 +++++---- .../appendix-application-properties.adoc | 5 +++ 21 files changed, 154 insertions(+), 120 deletions(-) diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/batch/BasicBatchConfigurer.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/batch/BasicBatchConfigurer.java index d8f07295fe..5437f5e407 100644 --- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/batch/BasicBatchConfigurer.java +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/batch/BasicBatchConfigurer.java @@ -30,10 +30,10 @@ import org.springframework.batch.core.launch.JobLauncher; import org.springframework.batch.core.launch.support.SimpleJobLauncher; import org.springframework.batch.core.repository.JobRepository; import org.springframework.batch.core.repository.support.JobRepositoryFactoryBean; -import org.springframework.boot.autoconfigure.transaction.TransactionProperties; import org.springframework.jdbc.datasource.DataSourceTransactionManager; import org.springframework.orm.jpa.JpaTransactionManager; import org.springframework.transaction.PlatformTransactionManager; +import org.springframework.transaction.support.AbstractPlatformTransactionManager; import org.springframework.util.StringUtils; /** @@ -49,8 +49,6 @@ public class BasicBatchConfigurer implements BatchConfigurer { private final BatchProperties properties; - private final TransactionProperties transactionProperties; - private final DataSource dataSource; private final EntityManagerFactory entityManagerFactory; @@ -66,24 +64,21 @@ public class BasicBatchConfigurer implements BatchConfigurer { /** * Create a new {@link BasicBatchConfigurer} instance. * @param properties the batch properties - * @param transactionProperties the transaction properties * @param dataSource the underlying data source */ - protected BasicBatchConfigurer(BatchProperties properties, TransactionProperties transactionProperties, DataSource dataSource) { - this(properties, transactionProperties, dataSource, null); + protected BasicBatchConfigurer(BatchProperties properties, DataSource dataSource) { + this(properties, dataSource, null); } /** * Create a new {@link BasicBatchConfigurer} instance. * @param properties the batch properties - * @param transactionProperties the transaction properties * @param dataSource the underlying data source * @param entityManagerFactory the entity manager factory (or {@code null}) */ - protected BasicBatchConfigurer(BatchProperties properties, TransactionProperties transactionProperties, DataSource dataSource, + protected BasicBatchConfigurer(BatchProperties properties, DataSource dataSource, EntityManagerFactory entityManagerFactory) { this.properties = properties; - this.transactionProperties = transactionProperties; this.entityManagerFactory = entityManagerFactory; this.dataSource = dataSource; } @@ -157,15 +152,16 @@ public class BasicBatchConfigurer implements BatchConfigurer { } protected PlatformTransactionManager createTransactionManager() { - PlatformTransactionManager txManager; + AbstractPlatformTransactionManager transactionManager = createAppropriateTransactionManager(); + this.properties.getTransaction().applyTo(transactionManager); + return transactionManager; + } + + private AbstractPlatformTransactionManager createAppropriateTransactionManager() { if (this.entityManagerFactory != null) { - txManager = new JpaTransactionManager(this.entityManagerFactory); - } - else { - txManager = new DataSourceTransactionManager(this.dataSource); + return new JpaTransactionManager(this.entityManagerFactory); } - this.transactionProperties.applyTo(txManager); - return txManager; + return new DataSourceTransactionManager(this.dataSource); } } diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/batch/BatchAutoConfiguration.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/batch/BatchAutoConfiguration.java index 44eefb73f7..2586c8621a 100644 --- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/batch/BatchAutoConfiguration.java +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/batch/BatchAutoConfiguration.java @@ -37,7 +37,6 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration; -import org.springframework.boot.autoconfigure.transaction.TransactionProperties; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -136,18 +135,16 @@ public class BatchAutoConfiguration { return factory; } - @EnableConfigurationProperties({BatchProperties.class, TransactionProperties.class}) + @EnableConfigurationProperties(BatchProperties.class) @ConditionalOnClass(value = PlatformTransactionManager.class, name = "javax.persistence.EntityManagerFactory") @ConditionalOnMissingBean(BatchConfigurer.class) @Configuration protected static class JpaBatchConfiguration { private final BatchProperties properties; - private final TransactionProperties transactionProperties; - protected JpaBatchConfiguration(BatchProperties properties, TransactionProperties transactionProperties) { + protected JpaBatchConfiguration(BatchProperties properties) { this.properties = properties; - this.transactionProperties = transactionProperties; } // The EntityManagerFactory may not be discoverable by type when this condition @@ -157,14 +154,14 @@ public class BatchAutoConfiguration { @ConditionalOnBean(name = "entityManagerFactory") public BasicBatchConfigurer jpaBatchConfigurer(DataSource dataSource, EntityManagerFactory entityManagerFactory) { - return new BasicBatchConfigurer(this.properties, this.transactionProperties, dataSource, + return new BasicBatchConfigurer(this.properties, dataSource, entityManagerFactory); } @Bean @ConditionalOnMissingBean(name = "entityManagerFactory") public BasicBatchConfigurer basicBatchConfigurer(DataSource dataSource) { - return new BasicBatchConfigurer(this.properties, this.transactionProperties, dataSource); + return new BasicBatchConfigurer(this.properties, dataSource); } } diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/batch/BatchProperties.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/batch/BatchProperties.java index 9582a05f34..998098416d 100644 --- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/batch/BatchProperties.java +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/batch/BatchProperties.java @@ -16,7 +16,9 @@ package org.springframework.boot.autoconfigure.batch; +import org.springframework.boot.autoconfigure.transaction.TransactionProperties; import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.boot.context.properties.NestedConfigurationProperty; /** * Configuration properties for Spring Batch. @@ -46,6 +48,9 @@ public class BatchProperties { private final Job job = new Job(); + @NestedConfigurationProperty + private final TransactionProperties transaction = new TransactionProperties(); + public String getSchema() { return this.schema; } @@ -54,6 +59,14 @@ public class BatchProperties { this.schema = schema; } + public String getTablePrefix() { + return this.tablePrefix; + } + + public void setTablePrefix(String tablePrefix) { + this.tablePrefix = tablePrefix; + } + public Initializer getInitializer() { return this.initializer; } @@ -62,12 +75,8 @@ public class BatchProperties { return this.job; } - public void setTablePrefix(String tablePrefix) { - this.tablePrefix = tablePrefix; - } - - public String getTablePrefix() { - return this.tablePrefix; + public TransactionProperties getTransaction() { + return this.transaction; } public class Initializer { diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jDataAutoConfiguration.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jDataAutoConfiguration.java index 19bbc4004e..f0a069b1b9 100644 --- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jDataAutoConfiguration.java +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jDataAutoConfiguration.java @@ -29,7 +29,6 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; import org.springframework.boot.autoconfigure.domain.EntityScanPackages; -import org.springframework.boot.autoconfigure.transaction.TransactionProperties; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Bean; @@ -53,9 +52,9 @@ import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter * @since 1.4.0 */ @Configuration -@ConditionalOnClass({SessionFactory.class, PlatformTransactionManager.class}) +@ConditionalOnClass({ SessionFactory.class, PlatformTransactionManager.class }) @ConditionalOnMissingBean(SessionFactory.class) -@EnableConfigurationProperties({Neo4jProperties.class, TransactionProperties.class}) +@EnableConfigurationProperties(Neo4jProperties.class) @SuppressWarnings("deprecation") public class Neo4jDataAutoConfiguration { @@ -90,9 +89,10 @@ public class Neo4jDataAutoConfiguration { @Bean @ConditionalOnMissingBean(PlatformTransactionManager.class) public Neo4jTransactionManager transactionManager(SessionFactory sessionFactory, - TransactionProperties transactionProperties) { - Neo4jTransactionManager transactionManager = new Neo4jTransactionManager(sessionFactory); - transactionProperties.applyTo(transactionManager); + Neo4jProperties properties) { + Neo4jTransactionManager transactionManager = new Neo4jTransactionManager( + sessionFactory); + properties.getTransaction().applyTo(transactionManager); return transactionManager; } diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jProperties.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jProperties.java index e58bda102b..030b69cee6 100644 --- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jProperties.java +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jProperties.java @@ -23,7 +23,9 @@ import org.neo4j.ogm.config.Configuration; import org.neo4j.ogm.config.DriverConfiguration; import org.springframework.beans.BeansException; +import org.springframework.boot.autoconfigure.transaction.TransactionProperties; import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.boot.context.properties.NestedConfigurationProperty; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import org.springframework.util.ClassUtils; @@ -69,6 +71,9 @@ public class Neo4jProperties implements ApplicationContextAware { private final Embedded embedded = new Embedded(); + @NestedConfigurationProperty + private final TransactionProperties transaction = new TransactionProperties(); + private ClassLoader classLoader = Neo4jProperties.class.getClassLoader(); public String getUri() { @@ -107,6 +112,10 @@ public class Neo4jProperties implements ApplicationContextAware { return this.embedded; } + public TransactionProperties getTransaction() { + return this.transaction; + } + @Override public void setApplicationContext(ApplicationContext ctx) throws BeansException { this.classLoader = ctx.getClassLoader(); diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/DataSourceProperties.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/DataSourceProperties.java index 6b79062f89..be1b5a130d 100644 --- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/DataSourceProperties.java +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/DataSourceProperties.java @@ -27,7 +27,9 @@ import javax.sql.DataSource; import org.springframework.beans.factory.BeanClassLoaderAware; import org.springframework.beans.factory.BeanCreationException; import org.springframework.beans.factory.InitializingBean; +import org.springframework.boot.autoconfigure.transaction.TransactionProperties; import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.boot.context.properties.NestedConfigurationProperty; import org.springframework.boot.jdbc.DatabaseDriver; import org.springframework.context.EnvironmentAware; import org.springframework.core.env.Environment; @@ -157,6 +159,9 @@ public class DataSourceProperties private String uniqueName; + @NestedConfigurationProperty + private final TransactionProperties transaction = new TransactionProperties(); + @Override public void setBeanClassLoader(ClassLoader classLoader) { this.classLoader = classLoader; @@ -473,6 +478,10 @@ public class DataSourceProperties this.xa = xa; } + public TransactionProperties getTransaction() { + return this.transaction; + } + /** * XA Specific datasource settings. */ diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/DataSourceTransactionManagerAutoConfiguration.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/DataSourceTransactionManagerAutoConfiguration.java index 7632f16196..931da19c9c 100644 --- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/DataSourceTransactionManagerAutoConfiguration.java +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/DataSourceTransactionManagerAutoConfiguration.java @@ -23,7 +23,6 @@ import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnSingleCandidate; -import org.springframework.boot.autoconfigure.transaction.TransactionProperties; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -46,11 +45,11 @@ import org.springframework.transaction.annotation.EnableTransactionManagement; @Configuration @ConditionalOnClass({ JdbcTemplate.class, PlatformTransactionManager.class }) @AutoConfigureOrder(Ordered.LOWEST_PRECEDENCE) +@EnableConfigurationProperties(DataSourceProperties.class) public class DataSourceTransactionManagerAutoConfiguration { @Configuration @ConditionalOnSingleCandidate(DataSource.class) - @EnableConfigurationProperties(TransactionProperties.class) static class DataSourceTransactionManagerConfiguration { private final DataSource dataSource; @@ -61,9 +60,11 @@ public class DataSourceTransactionManagerAutoConfiguration { @Bean @ConditionalOnMissingBean(PlatformTransactionManager.class) - public DataSourceTransactionManager transactionManager(TransactionProperties transactionProperties) { - DataSourceTransactionManager transactionManager = new DataSourceTransactionManager(this.dataSource); - transactionProperties.applyTo(transactionManager); + public DataSourceTransactionManager transactionManager( + DataSourceProperties properties) { + DataSourceTransactionManager transactionManager = new DataSourceTransactionManager( + this.dataSource); + properties.getTransaction().applyTo(transactionManager); return transactionManager; } diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/orm/jpa/JpaBaseConfiguration.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/orm/jpa/JpaBaseConfiguration.java index a4d05fd6b8..48f79d2ff0 100644 --- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/orm/jpa/JpaBaseConfiguration.java +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/orm/jpa/JpaBaseConfiguration.java @@ -34,7 +34,6 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; import org.springframework.boot.autoconfigure.domain.EntityScanPackages; -import org.springframework.boot.autoconfigure.transaction.TransactionProperties; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder; import org.springframework.context.annotation.Bean; @@ -62,7 +61,7 @@ import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter * @author Andy Wilkinson * @author Kazuki Shimizu */ -@EnableConfigurationProperties({JpaProperties.class, TransactionProperties.class}) +@EnableConfigurationProperties(JpaProperties.class) @Import(DataSourceInitializedPublisher.Registrar.class) public abstract class JpaBaseConfiguration implements BeanFactoryAware { @@ -83,9 +82,9 @@ public abstract class JpaBaseConfiguration implements BeanFactoryAware { @Bean @ConditionalOnMissingBean(PlatformTransactionManager.class) - public PlatformTransactionManager transactionManager(TransactionProperties transactionProperties) { + public PlatformTransactionManager transactionManager() { JpaTransactionManager transactionManager = new JpaTransactionManager(); - transactionProperties.applyTo(transactionManager); + this.properties.getTransaction().applyTo(transactionManager); return transactionManager; } diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/orm/jpa/JpaProperties.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/orm/jpa/JpaProperties.java index ecb118b4ff..aee5121b81 100644 --- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/orm/jpa/JpaProperties.java +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/orm/jpa/JpaProperties.java @@ -22,6 +22,7 @@ import java.util.Map; import javax.sql.DataSource; import org.springframework.boot.autoconfigure.jdbc.EmbeddedDatabaseConnection; +import org.springframework.boot.autoconfigure.transaction.TransactionProperties; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.context.properties.NestedConfigurationProperty; import org.springframework.orm.jpa.vendor.Database; @@ -67,6 +68,9 @@ public class JpaProperties { private Hibernate hibernate = new Hibernate(); + @NestedConfigurationProperty + private final TransactionProperties transaction = new TransactionProperties(); + public Map getProperties() { return this.properties; } @@ -125,6 +129,10 @@ public class JpaProperties { return this.hibernate.getAdditionalProperties(this.properties, dataSource); } + public TransactionProperties getTransaction() { + return this.transaction; + } + public static class Hibernate { private static final String USE_NEW_ID_GENERATOR_MAPPINGS = "hibernate.id." diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/transaction/TransactionProperties.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/transaction/TransactionProperties.java index 41a3499080..619c368b84 100644 --- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/transaction/TransactionProperties.java +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/transaction/TransactionProperties.java @@ -16,27 +16,24 @@ package org.springframework.boot.autoconfigure.transaction; -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.transaction.PlatformTransactionManager; import org.springframework.transaction.support.AbstractPlatformTransactionManager; /** - * External configuration properties for a {@link org.springframework.transaction.PlatformTransactionManager} created by - * Spring. All {@literal spring.transaction.} properties are also applied to the {@code PlatformTransactionManager}. + * Nested configuration properties that can be applied to an + * {@link AbstractPlatformTransactionManager}. * * @author Kazuki Shimizu * @since 1.5.0 */ -@ConfigurationProperties(prefix = "spring.transaction") public class TransactionProperties { /** - * The default transaction timeout (sec). + * Default transaction timeout in seconds. */ private Integer defaultTimeout; /** - * The indicating flag whether perform the rollback processing on commit failure (If perform rollback, set to the true). + * Perform the rollback on commit failurures. */ private Boolean rollbackOnCommitFailure; @@ -57,22 +54,15 @@ public class TransactionProperties { } /** - * Apply all transaction custom properties to a specified {@link PlatformTransactionManager} instance. - * + * Apply all transaction custom properties to the specified transaction manager. * @param transactionManager the target transaction manager - * @see AbstractPlatformTransactionManager#setDefaultTimeout(int) - * @see AbstractPlatformTransactionManager#setRollbackOnCommitFailure(boolean) */ - public void applyTo(PlatformTransactionManager transactionManager) { - if (transactionManager instanceof AbstractPlatformTransactionManager) { - AbstractPlatformTransactionManager abstractPlatformTransactionManager = - (AbstractPlatformTransactionManager) transactionManager; - if (this.defaultTimeout != null) { - abstractPlatformTransactionManager.setDefaultTimeout(this.defaultTimeout); - } - if (this.rollbackOnCommitFailure != null) { - abstractPlatformTransactionManager.setRollbackOnCommitFailure(this.rollbackOnCommitFailure); - } + public void applyTo(AbstractPlatformTransactionManager transactionManager) { + if (this.defaultTimeout != null) { + transactionManager.setDefaultTimeout(this.defaultTimeout); + } + if (this.rollbackOnCommitFailure != null) { + transactionManager.setRollbackOnCommitFailure(this.rollbackOnCommitFailure); } } diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/transaction/jta/AtomikosJtaConfiguration.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/transaction/jta/AtomikosJtaConfiguration.java index e5b6d7b37c..308fe36e7c 100644 --- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/transaction/jta/AtomikosJtaConfiguration.java +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/transaction/jta/AtomikosJtaConfiguration.java @@ -30,7 +30,6 @@ import com.atomikos.icatch.jta.UserTransactionManager; import org.springframework.boot.ApplicationHome; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.transaction.TransactionProperties; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.boot.jta.XAConnectionFactoryWrapper; import org.springframework.boot.jta.XADataSourceWrapper; @@ -55,17 +54,15 @@ import org.springframework.util.StringUtils; * @since 1.2.0 */ @Configuration -@EnableConfigurationProperties({AtomikosProperties.class, JtaProperties.class, TransactionProperties.class}) +@EnableConfigurationProperties({ AtomikosProperties.class, JtaProperties.class }) @ConditionalOnClass({ JtaTransactionManager.class, UserTransactionManager.class }) @ConditionalOnMissingBean(PlatformTransactionManager.class) class AtomikosJtaConfiguration { private final JtaProperties jtaProperties; - private final TransactionProperties transactionProperties; - AtomikosJtaConfiguration(JtaProperties jtaProperties, TransactionProperties transactionProperties) { + AtomikosJtaConfiguration(JtaProperties jtaProperties) { this.jtaProperties = jtaProperties; - this.transactionProperties = transactionProperties; } @Bean(initMethod = "init", destroyMethod = "shutdownForce") @@ -115,8 +112,9 @@ class AtomikosJtaConfiguration { @Bean public JtaTransactionManager transactionManager(UserTransaction userTransaction, TransactionManager transactionManager) { - JtaTransactionManager jtaTransactionManager = new JtaTransactionManager(userTransaction, transactionManager); - this.transactionProperties.applyTo(jtaTransactionManager); + JtaTransactionManager jtaTransactionManager = new JtaTransactionManager( + userTransaction, transactionManager); + this.jtaProperties.getTransaction().applyTo(jtaTransactionManager); return jtaTransactionManager; } diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/transaction/jta/BitronixJtaConfiguration.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/transaction/jta/BitronixJtaConfiguration.java index efcb403b94..36e27bc738 100644 --- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/transaction/jta/BitronixJtaConfiguration.java +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/transaction/jta/BitronixJtaConfiguration.java @@ -28,7 +28,6 @@ import bitronix.tm.jndi.BitronixContext; import org.springframework.boot.ApplicationHome; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.transaction.TransactionProperties; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.boot.jta.XAConnectionFactoryWrapper; @@ -52,17 +51,15 @@ import org.springframework.util.StringUtils; * @since 1.2.0 */ @Configuration -@EnableConfigurationProperties({JtaProperties.class, TransactionProperties.class}) +@EnableConfigurationProperties(JtaProperties.class) @ConditionalOnClass({ JtaTransactionManager.class, BitronixContext.class }) @ConditionalOnMissingBean(PlatformTransactionManager.class) class BitronixJtaConfiguration { private final JtaProperties jtaProperties; - private final TransactionProperties transactionProperties; - BitronixJtaConfiguration(JtaProperties jtaProperties, TransactionProperties transactionProperties) { + BitronixJtaConfiguration(JtaProperties jtaProperties) { this.jtaProperties = jtaProperties; - this.transactionProperties = transactionProperties; } @Bean @@ -111,8 +108,9 @@ class BitronixJtaConfiguration { @Bean public JtaTransactionManager transactionManager( TransactionManager transactionManager) { - JtaTransactionManager jtaTransactionManager = new JtaTransactionManager(transactionManager); - this.transactionProperties.applyTo(jtaTransactionManager); + JtaTransactionManager jtaTransactionManager = new JtaTransactionManager( + transactionManager); + this.jtaProperties.getTransaction().applyTo(jtaTransactionManager); return jtaTransactionManager; } diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/transaction/jta/JndiJtaConfiguration.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/transaction/jta/JndiJtaConfiguration.java index c35c62db5b..478a898a45 100644 --- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/transaction/jta/JndiJtaConfiguration.java +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/transaction/jta/JndiJtaConfiguration.java @@ -19,8 +19,6 @@ package org.springframework.boot.autoconfigure.transaction.jta; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnJndi; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.transaction.TransactionProperties; -import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.transaction.PlatformTransactionManager; @@ -41,19 +39,19 @@ import org.springframework.transaction.jta.JtaTransactionManager; "java:comp/TransactionManager", "java:appserver/TransactionManager", "java:pm/TransactionManager", "java:/TransactionManager" }) @ConditionalOnMissingBean(PlatformTransactionManager.class) -@EnableConfigurationProperties(TransactionProperties.class) class JndiJtaConfiguration { - private final TransactionProperties transactionProperties; + private final JtaProperties jtaProperties; - JndiJtaConfiguration(TransactionProperties transactionProperties) { - this.transactionProperties = transactionProperties; + JndiJtaConfiguration(JtaProperties jtaProperties) { + this.jtaProperties = jtaProperties; } @Bean public JtaTransactionManager transactionManager() { - JtaTransactionManager transactionManager = new JtaTransactionManagerFactoryBean().getObject(); - this.transactionProperties.applyTo(transactionManager); + JtaTransactionManager transactionManager = new JtaTransactionManagerFactoryBean() + .getObject(); + this.jtaProperties.getTransaction().applyTo(transactionManager); return transactionManager; } diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/transaction/jta/JtaProperties.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/transaction/jta/JtaProperties.java index 124bba9434..bbf63e4b53 100644 --- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/transaction/jta/JtaProperties.java +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/transaction/jta/JtaProperties.java @@ -16,7 +16,9 @@ package org.springframework.boot.autoconfigure.transaction.jta; +import org.springframework.boot.autoconfigure.transaction.TransactionProperties; import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.boot.context.properties.NestedConfigurationProperty; import org.springframework.transaction.jta.JtaTransactionManager; /** @@ -42,6 +44,9 @@ public class JtaProperties { */ private String transactionManagerId; + @NestedConfigurationProperty + private final TransactionProperties transaction = new TransactionProperties(); + public void setLogDir(String logDir) { this.logDir = logDir; } @@ -58,4 +63,8 @@ public class JtaProperties { this.transactionManagerId = transactionManagerId; } + public TransactionProperties getTransaction() { + return this.transaction; + } + } diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/transaction/jta/NarayanaJtaConfiguration.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/transaction/jta/NarayanaJtaConfiguration.java index 99c98f7f8f..ec97194374 100644 --- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/transaction/jta/NarayanaJtaConfiguration.java +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/transaction/jta/NarayanaJtaConfiguration.java @@ -28,7 +28,6 @@ import org.jboss.tm.XAResourceRecoveryRegistry; import org.springframework.boot.ApplicationHome; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.transaction.TransactionProperties; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.boot.jta.XAConnectionFactoryWrapper; import org.springframework.boot.jta.XADataSourceWrapper; @@ -56,15 +55,13 @@ import org.springframework.util.StringUtils; @ConditionalOnClass({ JtaTransactionManager.class, com.arjuna.ats.jta.UserTransaction.class, XAResourceRecoveryRegistry.class }) @ConditionalOnMissingBean(PlatformTransactionManager.class) -@EnableConfigurationProperties({JtaProperties.class, TransactionProperties.class}) +@EnableConfigurationProperties(JtaProperties.class) public class NarayanaJtaConfiguration { private final JtaProperties jtaProperties; - private final TransactionProperties transactionProperties; - public NarayanaJtaConfiguration(JtaProperties jtaProperties, TransactionProperties transactionProperties) { + public NarayanaJtaConfiguration(JtaProperties jtaProperties) { this.jtaProperties = jtaProperties; - this.transactionProperties = transactionProperties; } @Bean @@ -122,8 +119,9 @@ public class NarayanaJtaConfiguration { @Bean public JtaTransactionManager transactionManager(UserTransaction userTransaction, TransactionManager transactionManager) { - JtaTransactionManager jtaTransactionManager = new JtaTransactionManager(userTransaction, transactionManager); - this.transactionProperties.applyTo(jtaTransactionManager); + JtaTransactionManager jtaTransactionManager = new JtaTransactionManager( + userTransaction, transactionManager); + this.jtaProperties.getTransaction().applyTo(jtaTransactionManager); return jtaTransactionManager; } diff --git a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/batch/BatchAutoConfigurationTests.java b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/batch/BatchAutoConfigurationTests.java index e793ef3e44..327ee070ca 100644 --- a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/batch/BatchAutoConfigurationTests.java +++ b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/batch/BatchAutoConfigurationTests.java @@ -70,6 +70,7 @@ import static org.assertj.core.api.Assertions.assertThat; * @author Dave Syer * @author Stephane Nicoll * @author Vedran Pavic + * @author Kazuki Shimizu */ public class BatchAutoConfigurationTests { @@ -273,8 +274,8 @@ public class BatchAutoConfigurationTests { public void testCustomizeJpaTransactionManagerUsingProperties() throws Exception { this.context = new AnnotationConfigApplicationContext(); EnvironmentTestUtils.addEnvironment(this.context, - "spring.transaction.default-timeout:30", - "spring.transaction.rollback-on-commit-failure:true"); + "spring.batch.transaction.default-timeout:30", + "spring.batch.transaction.rollback-on-commit-failure:true"); this.context.register(TestConfiguration.class, EmbeddedDataSourceConfiguration.class, HibernateJpaAutoConfiguration.class, BatchAutoConfiguration.class, @@ -288,19 +289,20 @@ public class BatchAutoConfigurationTests { } @Test - public void testCustomizeDataSourceTransactionManagerUsingProperties() throws Exception { + public void testCustomizeDataSourceTransactionManagerUsingProperties() + throws Exception { this.context = new AnnotationConfigApplicationContext(); EnvironmentTestUtils.addEnvironment(this.context, - "spring.transaction.default-timeout:30", - "spring.transaction.rollback-on-commit-failure:true"); + "spring.batch.transaction.default-timeout:30", + "spring.batch.transaction.rollback-on-commit-failure:true"); this.context.register(TestConfiguration.class, - EmbeddedDataSourceConfiguration.class, - BatchAutoConfiguration.class, + EmbeddedDataSourceConfiguration.class, BatchAutoConfiguration.class, PropertyPlaceholderAutoConfiguration.class); this.context.refresh(); this.context.getBean(BatchConfigurer.class); - DataSourceTransactionManager transactionManager = DataSourceTransactionManager.class.cast( - this.context.getBean(BatchConfigurer.class).getTransactionManager()); + DataSourceTransactionManager transactionManager = DataSourceTransactionManager.class + .cast(this.context.getBean(BatchConfigurer.class) + .getTransactionManager()); assertThat(transactionManager.getDefaultTimeout()).isEqualTo(30); assertThat(transactionManager.isRollbackOnCommitFailure()).isTrue(); } diff --git a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jDataAutoConfigurationTests.java b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jDataAutoConfigurationTests.java index 49031a48bd..38044b7488 100644 --- a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jDataAutoConfigurationTests.java +++ b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/neo4j/Neo4jDataAutoConfigurationTests.java @@ -54,6 +54,7 @@ import static org.mockito.Mockito.verify; * @author Michael Hunger * @author Vince Bickers * @author Andy Wilkinson + * @author Kazuki Shimizu */ @SuppressWarnings("deprecation") public class Neo4jDataAutoConfigurationTests { @@ -81,10 +82,10 @@ public class Neo4jDataAutoConfigurationTests { @Test public void customNeo4jTransactionManagerUsingProperties() { - load(null, - "spring.transaction.default-timeout=30", - "spring.transaction.rollback-on-commit-failure:true"); - Neo4jTransactionManager transactionManager = this.context.getBean(Neo4jTransactionManager.class); + load(null, "spring.data.neo4j.transaction.default-timeout=30", + "spring.data.neo4j.transaction.rollback-on-commit-failure:true"); + Neo4jTransactionManager transactionManager = this.context + .getBean(Neo4jTransactionManager.class); assertThat(transactionManager.getDefaultTimeout()).isEqualTo(30); assertThat(transactionManager.isRollbackOnCommitFailure()).isTrue(); } diff --git a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jdbc/DataSourceTransactionManagerAutoConfigurationTests.java b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jdbc/DataSourceTransactionManagerAutoConfigurationTests.java index 70ea23679e..16c331edc7 100644 --- a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jdbc/DataSourceTransactionManagerAutoConfigurationTests.java +++ b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jdbc/DataSourceTransactionManagerAutoConfigurationTests.java @@ -108,14 +108,16 @@ public class DataSourceTransactionManagerAutoConfigurationTests { } @Test - public void testCustomizeDataSourceTransactionManagerUsingProperties() throws Exception { + public void testCustomizeDataSourceTransactionManagerUsingProperties() + throws Exception { EnvironmentTestUtils.addEnvironment(this.context, - "spring.transaction.default-timeout:30", - "spring.transaction.rollback-on-commit-failure:true"); + "spring.datasource.transaction.default-timeout:30", + "spring.datasource.transaction.rollback-on-commit-failure:true"); this.context.register(EmbeddedDataSourceConfiguration.class, DataSourceTransactionManagerAutoConfiguration.class); this.context.refresh(); - DataSourceTransactionManager transactionManager = this.context.getBean(DataSourceTransactionManager.class); + DataSourceTransactionManager transactionManager = this.context + .getBean(DataSourceTransactionManager.class); assertThat(transactionManager.getDefaultTimeout()).isEqualTo(30); assertThat(transactionManager.isRollbackOnCommitFailure()).isTrue(); } diff --git a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaAutoConfigurationTests.java b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaAutoConfigurationTests.java index ff67fcf246..a45cbba8d5 100644 --- a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaAutoConfigurationTests.java +++ b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaAutoConfigurationTests.java @@ -49,6 +49,7 @@ import static org.assertj.core.api.Assertions.assertThat; * @author Dave Syer * @author Phillip Webb * @author Andy Wilkinson + * @author Kazuki Shimizu */ public class HibernateJpaAutoConfigurationTests extends AbstractJpaAutoConfigurationTests { @@ -175,11 +176,12 @@ public class HibernateJpaAutoConfigurationTests @Test public void testCustomJpaTransactionManagerUsingProperties() throws Exception { EnvironmentTestUtils.addEnvironment(this.context, - "spring.transaction.default-timeout:30", - "spring.transaction.rollback-on-commit-failure:true"); + "spring.jpa.transaction.default-timeout:30", + "spring.jpa.transaction.rollback-on-commit-failure:true"); setupTestConfiguration(); this.context.refresh(); - JpaTransactionManager transactionManager = context.getBean(JpaTransactionManager.class); + JpaTransactionManager transactionManager = this.context + .getBean(JpaTransactionManager.class); assertThat(transactionManager.getDefaultTimeout()).isEqualTo(30); assertThat(transactionManager.isRollbackOnCommitFailure()).isTrue(); } diff --git a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/transaction/jta/JtaAutoConfigurationTests.java b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/transaction/jta/JtaAutoConfigurationTests.java index 2193e59155..70239874a6 100644 --- a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/transaction/jta/JtaAutoConfigurationTests.java +++ b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/transaction/jta/JtaAutoConfigurationTests.java @@ -69,6 +69,7 @@ import static org.mockito.Mockito.mock; * @author Josh Long * @author Phillip Webb * @author Andy Wilkinson + * @author Kazuki Shimizu */ public class JtaAutoConfigurationTests { @@ -249,11 +250,12 @@ public class JtaAutoConfigurationTests { public void atomikosCustomizeJtaTransactionManagerUsingProperties() throws Exception { this.context = new AnnotationConfigApplicationContext(); EnvironmentTestUtils.addEnvironment(this.context, - "spring.transaction.default-timeout:30", - "spring.transaction.rollback-on-commit-failure:true"); + "spring.jta.transaction.default-timeout:30", + "spring.jta.transaction.rollback-on-commit-failure:true"); this.context.register(AtomikosJtaConfiguration.class); this.context.refresh(); - JtaTransactionManager transactionManager = this.context.getBean(JtaTransactionManager.class); + JtaTransactionManager transactionManager = this.context + .getBean(JtaTransactionManager.class); assertThat(transactionManager.getDefaultTimeout()).isEqualTo(30); assertThat(transactionManager.isRollbackOnCommitFailure()).isTrue(); } @@ -262,11 +264,12 @@ public class JtaAutoConfigurationTests { public void bitronixCustomizeJtaTransactionManagerUsingProperties() throws Exception { this.context = new AnnotationConfigApplicationContext(); EnvironmentTestUtils.addEnvironment(this.context, - "spring.transaction.default-timeout:30", - "spring.transaction.rollback-on-commit-failure:true"); + "spring.jta.transaction.default-timeout:30", + "spring.jta.transaction.rollback-on-commit-failure:true"); this.context.register(BitronixJtaConfiguration.class); this.context.refresh(); - JtaTransactionManager transactionManager = this.context.getBean(JtaTransactionManager.class); + JtaTransactionManager transactionManager = this.context + .getBean(JtaTransactionManager.class); assertThat(transactionManager.getDefaultTimeout()).isEqualTo(30); assertThat(transactionManager.isRollbackOnCommitFailure()).isTrue(); } diff --git a/spring-boot-docs/src/main/asciidoc/appendix-application-properties.adoc b/spring-boot-docs/src/main/asciidoc/appendix-application-properties.adoc index 43267fbfce..196d51c2f4 100644 --- a/spring-boot-docs/src/main/asciidoc/appendix-application-properties.adoc +++ b/spring-boot-docs/src/main/asciidoc/appendix-application-properties.adoc @@ -582,6 +582,7 @@ content into your application; rather pick only the properties that you need. spring.data.neo4j.open-in-view=false # Register OpenSessionInViewInterceptor. Binds a Neo4j Session to the thread for the entire processing of the request. spring.data.neo4j.password= # Login password of the server. spring.data.neo4j.repositories.enabled=true # Enable Neo4j repositories. + spring.data.neo4j.transaction.*= # Transaction manager settings spring.data.neo4j.uri= # URI used by the driver. Auto-detected by default. spring.data.neo4j.username= # Login user of the server. @@ -623,6 +624,7 @@ content into your application; rather pick only the properties that you need. spring.datasource.separator=; # Statement separator in SQL initialization scripts. spring.datasource.sql-script-encoding= # SQL scripts encoding. spring.datasource.tomcat.*= # Tomcat datasource specific settings + spring.datasource.transaction.*= # Transaction manager settings spring.datasource.type= # Fully qualified name of the connection pool implementation to use. By default, it is auto-detected from the classpath. spring.datasource.url= # JDBC url of the database. spring.datasource.username= @@ -658,10 +660,12 @@ content into your application; rather pick only the properties that you need. spring.jpa.open-in-view=true # Register OpenEntityManagerInViewInterceptor. Binds a JPA EntityManager to the thread for the entire processing of the request. spring.jpa.properties.*= # Additional native properties to set on the JPA provider. spring.jpa.show-sql=false # Enable logging of SQL statements. + spring.jpa.transaction.*= # Transaction manager settings # JTA ({sc-spring-boot-autoconfigure}/transaction/jta/JtaAutoConfiguration.{sc-ext}[JtaAutoConfiguration]) spring.jta.enabled=true # Enable JTA support. spring.jta.log-dir= # Transaction logs directory. + spring.jta.transaction.*= # Transaction manager settings spring.jta.transaction-manager-id= # Transaction manager unique identifier. # ATOMIKOS ({sc-spring-boot}/jta/atomikos/AtomikosProperties.{sc-ext}[AtomikosProperties]) @@ -844,6 +848,7 @@ content into your application; rather pick only the properties that you need. spring.batch.job.names= # Comma-separated list of job names to execute on startup (For instance `job1,job2`). By default, all Jobs found in the context are executed. spring.batch.schema=classpath:org/springframework/batch/core/schema-@@platform@@.sql # Path to the SQL file to use to initialize the database schema. spring.batch.table-prefix= # Table prefix for all the batch meta-data tables. + spring.batch.transaction.*= # Transaction manager settings # JMS ({sc-spring-boot-autoconfigure}/jms/JmsProperties.{sc-ext}[JmsProperties]) spring.jms.jndi-name= # Connection factory JNDI name. When set, takes precedence to others connection factory auto-configurations.