ARTEMIS-2955 commons-dbcp2 performance issue with Derby Embedded DBMS
This commit is fixing: - a missing commit that can make leak a connection - restricting default specific commons-dbcp2 to the default data source - setting poolPreparedStatements true by default - configured embedded Derby to be in-memory to speedup tests
This commit is contained in:
parent
0077f354cd
commit
769101ac69
|
@ -132,6 +132,7 @@ public abstract class AbstractJDBCDriver {
|
||||||
logger.tracef("Table %s did exist but is empty. Starting initialization.", tableName);
|
logger.tracef("Table %s did exist but is empty. Starting initialization.", tableName);
|
||||||
} else {
|
} else {
|
||||||
logger.tracef("Table %s did exist but is empty. Initialization completed: no initialization statements left.", tableName);
|
logger.tracef("Table %s did exist but is empty. Initialization completed: no initialization statements left.", tableName);
|
||||||
|
connection.commit();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
|
|
|
@ -24,6 +24,7 @@ import java.util.concurrent.Executor;
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
|
||||||
import org.apache.activemq.artemis.jdbc.store.logging.LoggingConnection;
|
import org.apache.activemq.artemis.jdbc.store.logging.LoggingConnection;
|
||||||
|
import org.apache.activemq.artemis.jdbc.store.sql.PropertySQLProvider;
|
||||||
import org.apache.activemq.artemis.journal.ActiveMQJournalLogger;
|
import org.apache.activemq.artemis.journal.ActiveMQJournalLogger;
|
||||||
import org.jboss.logging.Logger;
|
import org.jboss.logging.Logger;
|
||||||
|
|
||||||
|
@ -34,19 +35,31 @@ public class JDBCConnectionProvider {
|
||||||
private Executor networkTimeoutExecutor;
|
private Executor networkTimeoutExecutor;
|
||||||
private int networkTimeoutMillis;
|
private int networkTimeoutMillis;
|
||||||
private boolean supportNetworkTimeout;
|
private boolean supportNetworkTimeout;
|
||||||
|
private final String user;
|
||||||
|
private final String password;
|
||||||
|
|
||||||
public JDBCConnectionProvider(DataSource dataSource) {
|
public JDBCConnectionProvider(DataSource dataSource) {
|
||||||
|
this(dataSource, null, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public JDBCConnectionProvider(DataSource dataSource, String user, String password) {
|
||||||
this.dataSource = dataSource;
|
this.dataSource = dataSource;
|
||||||
this.networkTimeoutExecutor = null;
|
this.networkTimeoutExecutor = null;
|
||||||
this.networkTimeoutMillis = -1;
|
this.networkTimeoutMillis = -1;
|
||||||
this.supportNetworkTimeout = true;
|
this.supportNetworkTimeout = true;
|
||||||
|
this.user = user;
|
||||||
|
this.password = password;
|
||||||
addDerbyShutdownHook();
|
addDerbyShutdownHook();
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized Connection getConnection() throws SQLException {
|
public synchronized Connection getConnection() throws SQLException {
|
||||||
Connection connection;
|
Connection connection;
|
||||||
try {
|
try {
|
||||||
|
if (user != null || password != null) {
|
||||||
|
connection = dataSource.getConnection(user, password);
|
||||||
|
} else {
|
||||||
connection = dataSource.getConnection();
|
connection = dataSource.getConnection();
|
||||||
|
}
|
||||||
if (logger.isTraceEnabled() && !(connection instanceof LoggingConnection)) {
|
if (logger.isTraceEnabled() && !(connection instanceof LoggingConnection)) {
|
||||||
connection = new LoggingConnection(connection, logger);
|
connection = new LoggingConnection(connection, logger);
|
||||||
}
|
}
|
||||||
|
@ -92,7 +105,8 @@ public class JDBCConnectionProvider {
|
||||||
public void addDerbyShutdownHook() {
|
public void addDerbyShutdownHook() {
|
||||||
// Shutdown the derby if using the derby embedded driver.
|
// Shutdown the derby if using the derby embedded driver.
|
||||||
try (Connection connection = getConnection()) {
|
try (Connection connection = getConnection()) {
|
||||||
if (connection.getMetaData().getDriverName().equals("org.apache.derby.jdbc.EmbeddedDriver")) {
|
PropertySQLProvider.Factory.SQLDialect sqlDialect = PropertySQLProvider.Factory.investigateDialect(connection);
|
||||||
|
if (sqlDialect == PropertySQLProvider.Factory.SQLDialect.DERBY) {
|
||||||
if (shutAdded.compareAndSet(false, true)) {
|
if (shutAdded.compareAndSet(false, true)) {
|
||||||
Runtime.getRuntime().addShutdownHook(new ShutdownDerby());
|
Runtime.getRuntime().addShutdownHook(new ShutdownDerby());
|
||||||
}
|
}
|
||||||
|
|
|
@ -151,7 +151,8 @@ public class DatabaseStorageConfiguration implements StoreConfiguration {
|
||||||
*/
|
*/
|
||||||
private DataSource getDataSource() {
|
private DataSource getDataSource() {
|
||||||
if (dataSource == null) {
|
if (dataSource == null) {
|
||||||
if (dataSourceProperties.isEmpty()) {
|
// the next settings are going to be applied only if the datasource is the default one
|
||||||
|
if (dataSourceProperties.isEmpty() && ActiveMQDefaultConfiguration.getDefaultDataSourceClassName().equals(dataSourceClassName)) {
|
||||||
addDataSourceProperty("driverClassName", jdbcDriverClassName);
|
addDataSourceProperty("driverClassName", jdbcDriverClassName);
|
||||||
addDataSourceProperty("url", jdbcConnectionUrl);
|
addDataSourceProperty("url", jdbcConnectionUrl);
|
||||||
if (jdbcUser != null) {
|
if (jdbcUser != null) {
|
||||||
|
@ -162,6 +163,8 @@ public class DatabaseStorageConfiguration implements StoreConfiguration {
|
||||||
}
|
}
|
||||||
// Let the pool to have unbounded number of connections by default to prevent connection starvation
|
// Let the pool to have unbounded number of connections by default to prevent connection starvation
|
||||||
addDataSourceProperty("maxTotal", "-1");
|
addDataSourceProperty("maxTotal", "-1");
|
||||||
|
// Let the pool to have unbounded number of cached prepared statements to save the initialization cost
|
||||||
|
addDataSourceProperty("poolPreparedStatements", "true");
|
||||||
}
|
}
|
||||||
dataSource = JDBCDataSourceUtils.getDataSource(dataSourceClassName, dataSourceProperties);
|
dataSource = JDBCDataSourceUtils.getDataSource(dataSourceClassName, dataSourceProperties);
|
||||||
}
|
}
|
||||||
|
@ -179,7 +182,12 @@ public class DatabaseStorageConfiguration implements StoreConfiguration {
|
||||||
|
|
||||||
public JDBCConnectionProvider getConnectionProvider() {
|
public JDBCConnectionProvider getConnectionProvider() {
|
||||||
if (connectionProvider == null) {
|
if (connectionProvider == null) {
|
||||||
|
// commons-dbcp2 doesn't support DataSource::getConnection(user, password)
|
||||||
|
if (dataSourceClassName == ActiveMQDefaultConfiguration.getDefaultDataSourceClassName()) {
|
||||||
connectionProvider = new JDBCConnectionProvider(getDataSource());
|
connectionProvider = new JDBCConnectionProvider(getDataSource());
|
||||||
|
} else {
|
||||||
|
connectionProvider = new JDBCConnectionProvider(getDataSource(), getJdbcUser(), getJdbcPassword());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return connectionProvider;
|
return connectionProvider;
|
||||||
}
|
}
|
||||||
|
|
|
@ -257,6 +257,10 @@ public abstract class ActiveMQTestBase extends Assert {
|
||||||
|
|
||||||
@After
|
@After
|
||||||
public void shutdownDerby() {
|
public void shutdownDerby() {
|
||||||
|
try {
|
||||||
|
DriverManager.getConnection("jdbc:derby:" + getEmbeddedDataBaseName() + ";destroy=true");
|
||||||
|
} catch (Exception ignored) {
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
DriverManager.getConnection("jdbc:derby:;shutdown=true");
|
DriverManager.getConnection("jdbc:derby:;shutdown=true");
|
||||||
} catch (Exception ignored) {
|
} catch (Exception ignored) {
|
||||||
|
@ -837,8 +841,12 @@ public abstract class ActiveMQTestBase extends Assert {
|
||||||
return testDir;
|
return testDir;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private String getEmbeddedDataBaseName() {
|
||||||
|
return "memory:" + getTestDir();
|
||||||
|
}
|
||||||
|
|
||||||
protected final String getTestJDBCConnectionUrl() {
|
protected final String getTestJDBCConnectionUrl() {
|
||||||
return System.getProperty("jdbc.connection.url", "jdbc:derby:" + getTestDir() + File.separator + "derby;create=true");
|
return System.getProperty("jdbc.connection.url", "jdbc:derby:" + getEmbeddedDataBaseName() + ";create=true");
|
||||||
}
|
}
|
||||||
|
|
||||||
protected final String getJDBCClassName() {
|
protected final String getJDBCClassName() {
|
||||||
|
|
Loading…
Reference in New Issue