in src/main/java/org/mariadb/jdbc/internal/failover/FailoverProxy.java [161:295]
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
String methodName = method.getName();
switch (methodName) {
case METHOD_GET_LOCK:
return this.lock;
case METHOD_GET_NO_BACKSLASH:
return listener.noBackslashEscapes();
case METHOD_IS_MARIADB:
return listener.isServerMariaDb();
case METHOD_GET_CATALOG:
return listener.getCatalog();
case METHOD_GET_TIMEOUT:
return listener.getTimeout();
case METHOD_VERSION_GREATER_OR_EQUAL:
return listener.versionGreaterOrEqual((int) args[0], (int) args[1], (int) args[2]);
case METHOD_SESSION_STATE_AWARE:
return listener.sessionStateAware();
case METHOD_IS_EXPLICIT_CLOSED:
return listener.isExplicitClosed();
case METHOD_GET_OPTIONS:
return listener.getUrlParser().getOptions();
case METHOD_GET_MAJOR_VERSION:
return listener.getMajorServerVersion();
case METHOD_GET_SERVER_THREAD_ID:
return listener.getServerThreadId();
case METHOD_GET_URLPARSER:
return listener.getUrlParser();
case METHOD_GET_PROXY:
return this;
case METHOD_IS_CLOSED:
return listener.isClosed();
case METHOD_IS_VALID:
return listener.isValid((int) args[0]);
case METHOD_PROLOG:
listener.prolog((long) args[0], (MariaDbConnection) args[2], (MariaDbStatement) args[3]);
return null;
case METHOD_EXECUTE_QUERY:
boolean isClosed = this.listener.isClosed();
try {
this.listener.preExecute();
} catch (SQLException e) {
// handle failover only if connection error
// normal error can be thrown upon reconnection if there was a transaction in progress.
if (hasToHandleFailover(e)) {
return handleFailOver(e, method, args, listener.getCurrentProtocol(), isClosed);
}
}
break;
case METHOD_SET_READ_ONLY:
this.listener.switchReadOnlyConnection((Boolean) args[0]);
return null;
case METHOD_GET_READ_ONLY:
return this.listener.isReadOnly();
case METHOD_IN_TRANSACTION:
return this.listener.inTransaction();
case METHOD_IS_MASTER_CONNECTION:
return this.listener.isMasterConnection();
case METHOD_ABORT:
this.listener.preAbort();
return null;
case METHOD_CLOSED_EXPLICIT:
this.listener.preClose();
return null;
case METHOD_COM_MULTI_PREPARE_EXECUTES:
case METHOD_EXECUTE_PREPARED_QUERY:
boolean mustBeOnMaster = (Boolean) args[0];
ServerPrepareResult serverPrepareResult = (ServerPrepareResult) args[1];
if (serverPrepareResult != null) {
if (!mustBeOnMaster
&& serverPrepareResult.getUnProxiedProtocol().isMasterConnection()
&& !this.listener.hasHostFail()) {
// PrepareStatement was to be executed on slave, but since a failover was running on
// master connection. Slave connection is up
// again, so has to be re-prepared on slave
try {
logger.trace(
"re-prepare query \"{}\" on slave (was " + "temporary on master since failover)",
serverPrepareResult.getSql());
this.listener.rePrepareOnSlave(serverPrepareResult, false);
} catch (SQLException q) {
// error during re-prepare, will do executed on master.
}
}
boolean wasClosed = this.listener.isClosed();
try {
return listener.invoke(method, args, serverPrepareResult.getUnProxiedProtocol());
} catch (InvocationTargetException e) {
if (e.getTargetException() != null) {
if (e.getTargetException() instanceof SQLException
&& hasToHandleFailover((SQLException) e.getTargetException())) {
return handleFailOver(
(SQLException) e.getTargetException(),
method,
args,
serverPrepareResult.getUnProxiedProtocol(),
wasClosed);
}
throw e.getTargetException();
}
throw e;
}
}
break;
case METHOD_PROLOG_PROXY:
boolean wasClosed = this.listener.isClosed();
try {
if (args[0] != null) {
return listener.invoke(
method, args, ((ServerPrepareResult) args[0]).getUnProxiedProtocol());
}
return null;
} catch (InvocationTargetException e) {
if (e.getTargetException() != null) {
if (e.getTargetException() instanceof SQLException
&& hasToHandleFailover((SQLException) e.getTargetException())) {
return handleFailOver(
(SQLException) e.getTargetException(),
method,
args,
((ServerPrepareResult) args[0]).getUnProxiedProtocol(),
wasClosed);
}
throw e.getTargetException();
}
throw e;
}
case METHOD_RESET:
// listener will report reset on any active connections (Master/slave)
listener.reset();
return null;
default:
}
return executeInvocation(method, args, false);
}