From ee28ffc928381944ddec8df50d1572faf5d196dd 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. Fixes #9261 --- .../jpa/HibernateJpaAutoConfiguration.java | 24 +++++++++++++++++++ .../CommonsDbcp2DataSourcePoolMetadata.java | 5 ++++ .../jdbc/metadata/DataSourcePoolMetadata.java | 8 +++++++ .../HikariDataSourcePoolMetadata.java | 5 ++++ .../TomcatDataSourcePoolMetadata.java | 5 ++++ 5 files changed, 47 insertions(+) diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaAutoConfiguration.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaAutoConfiguration.java index 1f32bf7aebb8..4d75cc4a6a2e 100644 --- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaAutoConfiguration.java +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaAutoConfiguration.java @@ -17,6 +17,7 @@ package org.springframework.boot.autoconfigure.orm.jpa; import java.util.Arrays; +import java.util.Collection; import java.util.Collections; import java.util.LinkedHashMap; import java.util.List; @@ -40,6 +41,9 @@ import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration.HibernateEntityManagerCondition; 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.ConditionContext; import org.springframework.context.annotation.Conditional; @@ -73,6 +77,8 @@ public class HibernateJpaAutoConfiguration 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. */ @@ -89,16 +95,19 @@ public class HibernateJpaAutoConfiguration extends JpaBaseConfiguration { "org.hibernate.service.jta.platform.internal.WebSphereExtendedJtaPlatform", }; private final HibernateDefaultDdlAutoProvider defaultDdlAutoProvider; + private final Collection metadataProviders; public HibernateJpaAutoConfiguration(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 @@ -121,6 +130,9 @@ protected void customizeVendorProperties(Map vendorProperties) { if (!vendorProperties.containsKey(JTA_PLATFORM)) { configureJtaPlatform(vendorProperties); } + if (!vendorProperties.containsKey(PROVIDER_DISABLES_AUTOCOMMIT)) { + configureProviderDisablesAutocommit(vendorProperties); + } } private void configureJtaPlatform(Map vendorProperties) @@ -142,6 +154,18 @@ private void configureJtaPlatform(Map vendorProperties) } } + 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/src/main/java/org/springframework/boot/jdbc/metadata/CommonsDbcp2DataSourcePoolMetadata.java b/spring-boot/src/main/java/org/springframework/boot/jdbc/metadata/CommonsDbcp2DataSourcePoolMetadata.java index 58e5e29c9647..80ad21844894 100644 --- a/spring-boot/src/main/java/org/springframework/boot/jdbc/metadata/CommonsDbcp2DataSourcePoolMetadata.java +++ b/spring-boot/src/main/java/org/springframework/boot/jdbc/metadata/CommonsDbcp2DataSourcePoolMetadata.java @@ -53,4 +53,9 @@ public String getValidationQuery() { return getDataSource().getValidationQuery(); } + @Override + public Boolean getDefaultAutoCommit() { + return getDataSource().getDefaultAutoCommit(); + } + } diff --git a/spring-boot/src/main/java/org/springframework/boot/jdbc/metadata/DataSourcePoolMetadata.java b/spring-boot/src/main/java/org/springframework/boot/jdbc/metadata/DataSourcePoolMetadata.java index 635cc6b87d66..112b58fd0746 100644 --- a/spring-boot/src/main/java/org/springframework/boot/jdbc/metadata/DataSourcePoolMetadata.java +++ b/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/src/main/java/org/springframework/boot/jdbc/metadata/HikariDataSourcePoolMetadata.java b/spring-boot/src/main/java/org/springframework/boot/jdbc/metadata/HikariDataSourcePoolMetadata.java index 251999aa5f0d..700691e8a8c4 100644 --- a/spring-boot/src/main/java/org/springframework/boot/jdbc/metadata/HikariDataSourcePoolMetadata.java +++ b/spring-boot/src/main/java/org/springframework/boot/jdbc/metadata/HikariDataSourcePoolMetadata.java @@ -66,4 +66,9 @@ public String getValidationQuery() { return getDataSource().getConnectionTestQuery(); } + @Override + public Boolean getDefaultAutoCommit() { + return getDataSource().isAutoCommit(); + } + } diff --git a/spring-boot/src/main/java/org/springframework/boot/jdbc/metadata/TomcatDataSourcePoolMetadata.java b/spring-boot/src/main/java/org/springframework/boot/jdbc/metadata/TomcatDataSourcePoolMetadata.java index 6e495bbe61a1..f4b64408c97c 100644 --- a/spring-boot/src/main/java/org/springframework/boot/jdbc/metadata/TomcatDataSourcePoolMetadata.java +++ b/spring-boot/src/main/java/org/springframework/boot/jdbc/metadata/TomcatDataSourcePoolMetadata.java @@ -53,4 +53,9 @@ public String getValidationQuery() { return getDataSource().getValidationQuery(); } + @Override + public Boolean getDefaultAutoCommit() { + return getDataSource().isDefaultAutoCommit(); + } + }