Skip to content

Commit

Permalink
reuse proxy-connection object
Browse files Browse the repository at this point in the history
  • Loading branch information
wizzardo committed May 16, 2024
1 parent 0ebe369 commit ca8a57f
Showing 1 changed file with 126 additions and 46 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,69 +4,33 @@
import javax.sql.ConnectionEventListener;
import javax.sql.PooledConnection;
import javax.sql.StatementEventListener;
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

public class SimplePooledConnection implements PooledConnection {

protected Connection physicalConnection;
protected volatile Connection proxyConnection;

// protected List<StatementEventListener> statementListeners = new ArrayList<>();
protected ProxyConnection proxyConnection;
protected List<ConnectionEventListener> connectionListeners = new ArrayList<>();

public SimplePooledConnection(Connection physicalConnection) {
this.physicalConnection = physicalConnection;
proxyConnection = new ProxyConnection();
}

@Override
public Connection getConnection() throws SQLException {
if (proxyConnection != null)
if (!proxyConnection.isClosed())
proxyConnection.close();

if (physicalConnection == null || physicalConnection.isClosed())
throw new SQLException("Connection is closed");

proxyConnection = new ConnectionAdapter(physicalConnection) {
boolean isClosed;

@Override
public void close() throws SQLException {
ConnectionEvent event = new ConnectionEvent(SimplePooledConnection.this);

for (int i = connectionListeners.size() - 1; i >= 0; i--) {
connectionListeners.get(i).connectionClosed(event);
}

if (!physicalConnection.getAutoCommit()) {
physicalConnection.rollback();
}
physicalConnection.setAutoCommit(true);
isClosed = true;
}

@Override
public boolean isClosed() throws SQLException {
if (!isClosed)
isClosed = super.isClosed();

return isClosed;
}

@Override
protected void onSQLException(SQLException e) {
if ("database connection closed".equals(e.getMessage())) {
ConnectionEvent event = new ConnectionEvent(SimplePooledConnection.this, e);

for (int i = connectionListeners.size() - 1; i >= 0; i--) {
connectionListeners.get(i).connectionErrorOccurred(event);
}
}
}
};

proxyConnection.reset();
return proxyConnection;
}

Expand Down Expand Up @@ -94,10 +58,8 @@ public List<ConnectionEventListener> getListeners() {
}

public void close() throws SQLException {
if (proxyConnection != null) {
connectionListeners.clear();
proxyConnection.close();
}
connectionListeners.clear();
proxyConnection.close();

if (physicalConnection != null) {
try {
Expand All @@ -107,4 +69,122 @@ public void close() throws SQLException {
}
}
}

protected class ProxyConnection extends ConnectionAdapter {
volatile boolean isClosed;
List<AutoCloseable> closeables = new ArrayList<>();

public ProxyConnection() {
super(SimplePooledConnection.this.physicalConnection);
}

public void reset() {
isClosed = false;
closeables.clear();
}

@Override
public void close() throws SQLException {
ConnectionEvent event = new ConnectionEvent(SimplePooledConnection.this);

for (int i = connectionListeners.size() - 1; i >= 0; i--) {
connectionListeners.get(i).connectionClosed(event);
}

if (!physicalConnection.getAutoCommit()) {
physicalConnection.rollback();
}
try {
for (AutoCloseable closeable : closeables) {
closeable.close();
}
} catch (Exception e) {
e.printStackTrace();
}
physicalConnection.setAutoCommit(true);
isClosed = true;
}

@Override
public boolean isClosed() throws SQLException {
if (!isClosed)
isClosed = super.isClosed();

return isClosed;
}

@Override
protected void onSQLException(SQLException e) {
if ("database connection closed".equals(e.getMessage())) {
ConnectionEvent event = new ConnectionEvent(SimplePooledConnection.this, e);

for (int i = connectionListeners.size() - 1; i >= 0; i--) {
connectionListeners.get(i).connectionErrorOccurred(event);
}
}
}

@Override
public PreparedStatement prepareStatement(String sql) throws SQLException {
PreparedStatement statement = super.prepareStatement(sql);
closeables.add(statement);
return statement;
}

@Override
public CallableStatement prepareCall(String sql) throws SQLException {
CallableStatement statement = super.prepareCall(sql);
closeables.add(statement);
return statement;
}

@Override
public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency) throws SQLException {
PreparedStatement statement = super.prepareStatement(sql, resultSetType, resultSetConcurrency);
closeables.add(statement);
return statement;
}

@Override
public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency) throws SQLException {
CallableStatement statement = super.prepareCall(sql, resultSetType, resultSetConcurrency);
closeables.add(statement);
return statement;
}

@Override
public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException {
PreparedStatement statement = super.prepareStatement(sql, resultSetType, resultSetConcurrency, resultSetHoldability);
closeables.add(statement);
return statement;
}

@Override
public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException {
CallableStatement statement = super.prepareCall(sql, resultSetType, resultSetConcurrency, resultSetHoldability);
closeables.add(statement);
return statement;
}

@Override
public PreparedStatement prepareStatement(String sql, int autoGeneratedKeys) throws SQLException {
PreparedStatement statement = super.prepareStatement(sql, autoGeneratedKeys);
closeables.add(statement);
return statement;
}

@Override
public PreparedStatement prepareStatement(String sql, int[] columnIndexes) throws SQLException {
PreparedStatement statement = super.prepareStatement(sql, columnIndexes);
closeables.add(statement);
return statement;
}

@Override
public PreparedStatement prepareStatement(String sql, String[] columnNames) throws SQLException {
PreparedStatement statement = super.prepareStatement(sql, columnNames);
closeables.add(statement);
return statement;
}
}
}

0 comments on commit ca8a57f

Please sign in to comment.