Skip to content

Commit

Permalink
[CONJ-884] ensure pool state when connection error occurs
Browse files Browse the repository at this point in the history
  • Loading branch information
rusher committed Jul 26, 2021
1 parent 98f1226 commit 2e55b07
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 46 deletions.
8 changes: 6 additions & 2 deletions src/main/java/org/mariadb/jdbc/MariaDbPooledConnection.java
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ public void fireStatementClosed(Statement st) {
* @param st statement
* @param ex exception
*/
public void fireStatementErrorOccured(Statement st, SQLException ex) {
public void fireStatementErrorOccurred(Statement st, SQLException ex) {
if (st instanceof PreparedStatement) {
StatementEvent event = new StatementEvent(this, (PreparedStatement) st, ex);
for (StatementEventListener listener : statementEventListeners) {
Expand All @@ -213,7 +213,7 @@ public void fireConnectionClosed() {
*
* @param ex exception
*/
public void fireConnectionErrorOccured(SQLException ex) {
public void fireConnectionErrorOccurred(SQLException ex) {
ConnectionEvent event = new ConnectionEvent(this, ex);
for (ConnectionEventListener listener : connectionEventListeners) {
listener.connectionErrorOccurred(event);
Expand Down Expand Up @@ -242,4 +242,8 @@ public AtomicLong getLastUsed() {
public void lastUsedToNow() {
lastUsed.set(System.nanoTime());
}

public void ensureValidation() {
lastUsed.set(0);
}
}
81 changes: 42 additions & 39 deletions src/main/java/org/mariadb/jdbc/MariaDbStatement.java
Original file line number Diff line number Diff line change
Expand Up @@ -245,35 +245,37 @@ private void stopTimeoutTask() {
* @return SQLException exception with new message in case of timer timeout.
*/
protected SQLException executeExceptionEpilogue(SQLException sqle) {
// if has a failover, closing the statement
if (sqle.getSQLState() != null && sqle.getSQLState().startsWith("08")) {
try {
close();
} catch (SQLException sqlee) {
// eat exception
try {
if (sqle.getErrorCode() == 1148 && !options.allowLocalInfile) {
return exceptionFactory
.raiseStatementError(connection, this)
.create(
"Usage of LOCAL INFILE is disabled. To use it enable it via the connection property allowLocalInfile=true",
"42000",
1148,
sqle);
}
}

if (sqle.getErrorCode() == 1148 && !options.allowLocalInfile) {
return exceptionFactory
.raiseStatementError(connection, this)
.create(
"Usage of LOCAL INFILE is disabled. "
+ "To use it enable it via the connection property allowLocalInfile=true",
"42000",
1148,
sqle);
}
if (isTimedout) {
return exceptionFactory
.raiseStatementError(connection, this)
.create("Query timed out", "70100", 1317, sqle);
}

if (isTimedout) {
return exceptionFactory
.raiseStatementError(connection, this)
.create("Query timed out", "70100", 1317, sqle);
}
SQLException sqlException = exceptionFactory.raiseStatementError(connection, this).create(sqle);
logger.error("error executing query", sqlException);
return sqlException;
} finally {
// if has a failover, closing the statement
if (sqle.getSQLState() != null && sqle.getSQLState().startsWith("08")) {
try {
close();
} catch (SQLException sqlee) {
// eat exception
}
}

SQLException sqlException = exceptionFactory.raiseStatementError(connection, this).create(sqle);
logger.error("error executing query", sqlException);
return sqlException;
}
}

protected void executeEpilogue() {
Expand All @@ -290,22 +292,23 @@ protected void executeBatchEpilogue() {
}

private SQLException handleFailoverAndTimeout(SQLException sqle) {

// if has a failover, closing the statement
if (sqle.getSQLState() != null && sqle.getSQLState().startsWith("08")) {
try {
close();
} catch (SQLException sqlee) {
// eat exception
try {
if (isTimedout) {
return exceptionFactory
.raiseStatementError(connection, this)
.create("Query timed out", "70100", 1317, sqle);
}
return sqle;
} finally {
// if has a failover, closing the statement
if (sqle.getSQLState() != null && sqle.getSQLState().startsWith("08")) {
try {
close();
} catch (SQLException sqlee) {
// eat exception
}
}
}

if (isTimedout) {
return exceptionFactory
.raiseStatementError(connection, this)
.create("Query timed out", "70100", 1317, sqle);
}
return sqle;
}

protected BatchUpdateException executeBatchExceptionEpilogue(SQLException initialSqle, int size) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,10 @@ private static SQLException createException(
}

if (connection != null && connection.pooledConnection != null) {
connection.pooledConnection.fireStatementErrorOccured(statement, returnEx);
connection.pooledConnection.fireStatementErrorOccurred(statement, returnEx);
if (returnEx instanceof SQLNonTransientConnectionException) {
connection.pooledConnection.fireConnectionErrorOccurred(returnEx);
}
}
return returnEx;
}
Expand Down
12 changes: 8 additions & 4 deletions src/main/java/org/mariadb/jdbc/internal/util/pool/Pool.java
Original file line number Diff line number Diff line change
Expand Up @@ -357,12 +357,16 @@ public void connectionClosed(ConnectionEvent event) {

@Override
public void connectionErrorOccurred(ConnectionEvent event) {

MariaDbPooledConnection item = ((MariaDbPooledConnection) event.getSource());
if (idleConnections.remove(item)) {
totalConnection.decrementAndGet();
}
totalConnection.decrementAndGet();
// if occurs when idle, remove from list
idleConnections.remove(item);
silentCloseConnection(item);

// ensure that other connection will be validated before being use
// since one connection failed, better to assume the other might as well
idleConnections.stream().forEach(c -> c.lastUsedToNow());

addConnectionRequest();
logger.debug(
"connection {} removed from pool {} due to having throw a Connection exception (total:{}, active:{}, pending:{})",
Expand Down

0 comments on commit 2e55b07

Please sign in to comment.