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
pull/10658/merge
Craig Andrews 7 years ago committed by Stephane Nicoll
parent 70ead0135b
commit d0e70e90de

@ -30,6 +30,9 @@ import org.springframework.beans.factory.ObjectProvider;
import org.springframework.boot.autoconfigure.condition.ConditionalOnSingleCandidate; import org.springframework.boot.autoconfigure.condition.ConditionalOnSingleCandidate;
import org.springframework.boot.autoconfigure.transaction.TransactionManagerCustomizers; import org.springframework.boot.autoconfigure.transaction.TransactionManagerCustomizers;
import org.springframework.boot.jdbc.SchemaManagementProvider; 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.boot.orm.jpa.hibernate.SpringJtaPlatform;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.jndi.JndiLocatorDelegate; 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 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. * {@code NoJtaPlatform} implementations for various Hibernate versions.
*/ */
@ -72,15 +77,18 @@ class HibernateJpaConfiguration extends JpaBaseConfiguration {
"org.hibernate.service.jta.platform.internal.WebSphereExtendedJtaPlatform", }; "org.hibernate.service.jta.platform.internal.WebSphereExtendedJtaPlatform", };
private final HibernateDefaultDdlAutoProvider defaultDdlAutoProvider; private final HibernateDefaultDdlAutoProvider defaultDdlAutoProvider;
private final Collection<DataSourcePoolMetadataProvider> metadataProviders;
HibernateJpaConfiguration(DataSource dataSource, JpaProperties jpaProperties, HibernateJpaConfiguration(DataSource dataSource, JpaProperties jpaProperties,
ObjectProvider<JtaTransactionManager> jtaTransactionManager, ObjectProvider<JtaTransactionManager> jtaTransactionManager,
ObjectProvider<TransactionManagerCustomizers> transactionManagerCustomizers, ObjectProvider<TransactionManagerCustomizers> transactionManagerCustomizers,
ObjectProvider<Collection<DataSourcePoolMetadataProvider>> metadataProviders,
ObjectProvider<List<SchemaManagementProvider>> providers) { ObjectProvider<List<SchemaManagementProvider>> providers) {
super(dataSource, jpaProperties, jtaTransactionManager, super(dataSource, jpaProperties, jtaTransactionManager,
transactionManagerCustomizers); transactionManagerCustomizers);
this.defaultDdlAutoProvider = new HibernateDefaultDdlAutoProvider( this.defaultDdlAutoProvider = new HibernateDefaultDdlAutoProvider(
providers.getIfAvailable(Collections::emptyList)); providers.getIfAvailable(Collections::emptyList));
this.metadataProviders = metadataProviders.getIfAvailable();
} }
@Override @Override
@ -103,6 +111,9 @@ class HibernateJpaConfiguration extends JpaBaseConfiguration {
if (!vendorProperties.containsKey(JTA_PLATFORM)) { if (!vendorProperties.containsKey(JTA_PLATFORM)) {
configureJtaPlatform(vendorProperties); configureJtaPlatform(vendorProperties);
} }
if (!vendorProperties.containsKey(PROVIDER_DISABLES_AUTOCOMMIT)) {
configureProviderDisablesAutocommit(vendorProperties);
}
} }
private void configureJtaPlatform(Map<String, Object> vendorProperties) private void configureJtaPlatform(Map<String, Object> vendorProperties)
@ -124,6 +135,18 @@ class HibernateJpaConfiguration extends JpaBaseConfiguration {
} }
} }
private void configureProviderDisablesAutocommit(Map<String, Object> 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() { private boolean runningOnWebSphere() {
return ClassUtils.isPresent( return ClassUtils.isPresent(
"com.ibm.websphere.jtaextensions." + "ExtendedJTATransaction", "com.ibm.websphere.jtaextensions." + "ExtendedJTATransaction",

@ -53,4 +53,9 @@ public class CommonsDbcp2DataSourcePoolMetadata
return getDataSource().getValidationQuery(); return getDataSource().getValidationQuery();
} }
@Override
public Boolean getDefaultAutoCommit() {
return getDataSource().getDefaultAutoCommit();
}
} }

@ -71,4 +71,12 @@ public interface DataSourcePoolMetadata {
*/ */
String getValidationQuery(); 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();
} }

@ -66,4 +66,9 @@ public class HikariDataSourcePoolMetadata
return getDataSource().getConnectionTestQuery(); return getDataSource().getConnectionTestQuery();
} }
@Override
public Boolean getDefaultAutoCommit() {
return getDataSource().isAutoCommit();
}
} }

@ -53,4 +53,9 @@ public class TomcatDataSourcePoolMetadata
return getDataSource().getValidationQuery(); return getDataSource().getValidationQuery();
} }
@Override
public Boolean getDefaultAutoCommit() {
return getDataSource().isDefaultAutoCommit();
}
} }

Loading…
Cancel
Save