do not be too smart, just do not close the data source in the provider, it is the pool which still must provide connections. This pool has to be externally closed

This commit is contained in:
Jörg Prante 2024-08-22 10:23:25 +02:00
parent ffd0b831f9
commit 844b288a18
3 changed files with 7 additions and 32 deletions

View file

@ -1,3 +1,3 @@
group = org.xbib group = org.xbib
name = database name = database
version = 2.1.2 version = 2.2.0

View file

@ -5,13 +5,10 @@ import org.xbib.jdbc.connection.pool.PoolDataSource;
import org.xbib.jdbc.query.util.Metric; import org.xbib.jdbc.query.util.Metric;
import javax.sql.DataSource; import javax.sql.DataSource;
import java.io.Closeable;
import java.io.IOException;
import java.sql.Connection; import java.sql.Connection;
import java.sql.DriverManager; import java.sql.DriverManager;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.Properties; import java.util.Properties;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Supplier; import java.util.function.Supplier;
import java.util.logging.Level; import java.util.logging.Level;
@ -23,7 +20,7 @@ import java.util.logging.Logger;
* of this laziness, the underlying resources require explicit cleanup by calling either * of this laziness, the underlying resources require explicit cleanup by calling either
* commitAndClose() or rollbackAndClose(). * commitAndClose() or rollbackAndClose().
*/ */
public final class DatabaseProvider implements Supplier<Database>, Closeable { public final class DatabaseProvider implements Supplier<Database> {
private static final Logger logger = Logger.getLogger(DatabaseProvider.class.getName()); private static final Logger logger = Logger.getLogger(DatabaseProvider.class.getName());
@ -47,7 +44,7 @@ public final class DatabaseProvider implements Supplier<Database>, Closeable {
return new DatabaseProviderBuilderImpl(ds, () -> { return new DatabaseProviderBuilderImpl(ds, () -> {
try { try {
if (ds == null) { if (ds == null) {
throw new NullPointerException(); throw new IllegalArgumentException("data source must not be null");
} }
return ds.getConnection(); return ds.getConnection();
} catch (Exception e) { } catch (Exception e) {
@ -287,9 +284,6 @@ public final class DatabaseProvider implements Supplier<Database>, Closeable {
if (database != null) { if (database != null) {
return database; return database;
} }
if (builder.isClosed()) {
throw new DatabaseException("Called get() on a DatabaseProvider after close()");
}
Metric metric = new Metric(logger.isLoggable(Level.FINE)); Metric metric = new Metric(logger.isLoggable(Level.FINE));
try { try {
connection = builder.connectionProvider.get(); connection = builder.connectionProvider.get();
@ -393,8 +387,7 @@ public final class DatabaseProvider implements Supplier<Database>, Closeable {
} }
} }
@Override public void close() {
public void close() throws IOException {
if (connection != null) { if (connection != null) {
try { try {
connection.close(); connection.close();
@ -402,28 +395,24 @@ public final class DatabaseProvider implements Supplier<Database>, Closeable {
logger.log(Level.SEVERE, "Unable to close the database connection", e); logger.log(Level.SEVERE, "Unable to close the database connection", e);
} }
} }
builder.close();
connection = null; connection = null;
database = null; database = null;
} }
private static class DatabaseProviderBuilderImpl implements DatabaseProviderBuilder, Closeable { private static class DatabaseProviderBuilderImpl implements DatabaseProviderBuilder {
private DataSource dataSource; private final DataSource dataSource;
private final Supplier<Connection> connectionProvider; private final Supplier<Connection> connectionProvider;
private final Options options; private final Options options;
private final AtomicBoolean closed;
private DatabaseProviderBuilderImpl(DataSource dataSource, private DatabaseProviderBuilderImpl(DataSource dataSource,
Supplier<Connection> connectionProvider, Supplier<Connection> connectionProvider,
Options options) { Options options) {
this.dataSource = dataSource; this.dataSource = dataSource;
this.connectionProvider = connectionProvider; this.connectionProvider = connectionProvider;
this.options = options; this.options = options;
this.closed = new AtomicBoolean(false);
} }
@Override @Override
@ -511,20 +500,5 @@ public final class DatabaseProvider implements Supplier<Database>, Closeable {
this.build().transact(tx); this.build().transact(tx);
} }
@Override
public void close() throws IOException {
if (closed.compareAndSet(false, true)) {
if (dataSource != null) {
if (dataSource instanceof Closeable) {
((Closeable) dataSource).close();
}
dataSource = null;
}
}
}
public boolean isClosed() {
return closed.get();
}
} }
} }

View file

@ -29,6 +29,7 @@ dependencyResolutionManagement {
} }
include 'jdbc-connection-pool' include 'jdbc-connection-pool'
include 'jdbc-pool'
include 'jdbc-query' include 'jdbc-query'
include 'jdbc-test' include 'jdbc-test'
include 'jdbc-mariadb' include 'jdbc-mariadb'