From d0e70e90de67c4cca3646800d4ddcd8a83246c17 Mon Sep 17 00:00:00 2001 From: Craig Andrews Date: Wed, 12 Jul 2017 14:52:36 -0400 Subject: [PATCH] When pool autocommit is disabled, inform Hibernate Starting with Hibernate 5.2.10, the JPA property `hibernate.connection.provider_disables_autocommit` should be set to true when the datasource has autocommit disabled in order to improve performance. See gh-9737 --- .../orm/jpa/HibernateJpaConfiguration.java | 23 +++++++++++++++++++ .../CommonsDbcp2DataSourcePoolMetadata.java | 5 ++++ .../jdbc/metadata/DataSourcePoolMetadata.java | 8 +++++++ .../HikariDataSourcePoolMetadata.java | 5 ++++ .../TomcatDataSourcePoolMetadata.java | 5 ++++ 5 files changed, 46 insertions(+) diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.java index 8269ccf73c..6be365608c 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.java @@ -30,6 +30,9 @@ import org.springframework.beans.factory.ObjectProvider; import org.springframework.boot.autoconfigure.condition.ConditionalOnSingleCandidate; import org.springframework.boot.autoconfigure.transaction.TransactionManagerCustomizers; import org.springframework.boot.jdbc.SchemaManagementProvider; +import org.springframework.boot.jdbc.metadata.CompositeDataSourcePoolMetadataProvider; +import org.springframework.boot.jdbc.metadata.DataSourcePoolMetadata; +import org.springframework.boot.jdbc.metadata.DataSourcePoolMetadataProvider; import org.springframework.boot.orm.jpa.hibernate.SpringJtaPlatform; import org.springframework.context.annotation.Configuration; import org.springframework.jndi.JndiLocatorDelegate; @@ -56,6 +59,8 @@ class HibernateJpaConfiguration extends JpaBaseConfiguration { private static final String JTA_PLATFORM = "hibernate.transaction.jta.platform"; + private static final String PROVIDER_DISABLES_AUTOCOMMIT = "hibernate.connection.provider_disables_autocommit"; + /** * {@code NoJtaPlatform} implementations for various Hibernate versions. */ @@ -72,15 +77,18 @@ class HibernateJpaConfiguration extends JpaBaseConfiguration { "org.hibernate.service.jta.platform.internal.WebSphereExtendedJtaPlatform", }; private final HibernateDefaultDdlAutoProvider defaultDdlAutoProvider; + private final Collection metadataProviders; HibernateJpaConfiguration(DataSource dataSource, JpaProperties jpaProperties, ObjectProvider jtaTransactionManager, ObjectProvider transactionManagerCustomizers, + ObjectProvider> metadataProviders, ObjectProvider> providers) { super(dataSource, jpaProperties, jtaTransactionManager, transactionManagerCustomizers); this.defaultDdlAutoProvider = new HibernateDefaultDdlAutoProvider( providers.getIfAvailable(Collections::emptyList)); + this.metadataProviders = metadataProviders.getIfAvailable(); } @Override @@ -103,6 +111,9 @@ class HibernateJpaConfiguration extends JpaBaseConfiguration { if (!vendorProperties.containsKey(JTA_PLATFORM)) { configureJtaPlatform(vendorProperties); } + if (!vendorProperties.containsKey(PROVIDER_DISABLES_AUTOCOMMIT)) { + configureProviderDisablesAutocommit(vendorProperties); + } } private void configureJtaPlatform(Map vendorProperties) @@ -124,6 +135,18 @@ class HibernateJpaConfiguration extends JpaBaseConfiguration { } } + private void configureProviderDisablesAutocommit(Map vendorProperties) { + CompositeDataSourcePoolMetadataProvider poolMetadataProvider = new CompositeDataSourcePoolMetadataProvider( + this.metadataProviders); + DataSourcePoolMetadata poolMetadata = poolMetadataProvider + .getDataSourcePoolMetadata(getDataSource()); + if (poolMetadata != null + && Boolean.FALSE.equals(poolMetadata.getDefaultAutoCommit()) + && getJtaTransactionManager() == null) { + vendorProperties.put(PROVIDER_DISABLES_AUTOCOMMIT, "true"); + } + } + private boolean runningOnWebSphere() { return ClassUtils.isPresent( "com.ibm.websphere.jtaextensions." + "ExtendedJTATransaction", diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/jdbc/metadata/CommonsDbcp2DataSourcePoolMetadata.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/jdbc/metadata/CommonsDbcp2DataSourcePoolMetadata.java index 58e5e29c96..80ad218448 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/jdbc/metadata/CommonsDbcp2DataSourcePoolMetadata.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/jdbc/metadata/CommonsDbcp2DataSourcePoolMetadata.java @@ -53,4 +53,9 @@ public class CommonsDbcp2DataSourcePoolMetadata return getDataSource().getValidationQuery(); } + @Override + public Boolean getDefaultAutoCommit() { + return getDataSource().getDefaultAutoCommit(); + } + } diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/jdbc/metadata/DataSourcePoolMetadata.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/jdbc/metadata/DataSourcePoolMetadata.java index 635cc6b87d..112b58fd07 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/jdbc/metadata/DataSourcePoolMetadata.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/jdbc/metadata/DataSourcePoolMetadata.java @@ -71,4 +71,12 @@ public interface DataSourcePoolMetadata { */ String getValidationQuery(); + /** + * The default auto-commit state of connections created by this pool. + * If not set ({@code null}), default is JDBC driver default + * (If set to null then the java.sql.Connection.setAutoCommit(boolean) method will not be called.) + * @return the default auto-commit state or {@code null} + */ + Boolean getDefaultAutoCommit(); + } diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/jdbc/metadata/HikariDataSourcePoolMetadata.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/jdbc/metadata/HikariDataSourcePoolMetadata.java index 251999aa5f..700691e8a8 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/jdbc/metadata/HikariDataSourcePoolMetadata.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/jdbc/metadata/HikariDataSourcePoolMetadata.java @@ -66,4 +66,9 @@ public class HikariDataSourcePoolMetadata return getDataSource().getConnectionTestQuery(); } + @Override + public Boolean getDefaultAutoCommit() { + return getDataSource().isAutoCommit(); + } + } diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/jdbc/metadata/TomcatDataSourcePoolMetadata.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/jdbc/metadata/TomcatDataSourcePoolMetadata.java index 6e495bbe61..f4b64408c9 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/jdbc/metadata/TomcatDataSourcePoolMetadata.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/jdbc/metadata/TomcatDataSourcePoolMetadata.java @@ -53,4 +53,9 @@ public class TomcatDataSourcePoolMetadata return getDataSource().getValidationQuery(); } + @Override + public Boolean getDefaultAutoCommit() { + return getDataSource().isDefaultAutoCommit(); + } + }