use of org.vibur.dbcp.pool.HookHolder.ConnHooksAccessor in project vibur-dbcp by vibur.
the class PoolOperations method getConnHolder.
/**
* Tries to take a {@code ConnHolder} object from the underlying object pool. If successful, never returns
* {@code null}.
*
* @param timeoutMs timeout in millis to pass to the underlying object pool {@code take} methods
* @throws SQLException to indicate a generic non-recoverable error that cannot be retried
* @throws SQLTimeoutException to indicate a non-recoverable error due to timeout that cannot be retried
* @throws ViburDBCPException to indicate a recoverable error that can be retried
*/
private ConnHolder getConnHolder(long timeoutMs) throws SQLException, ViburDBCPException {
Hook.GetConnection[] onGet = ((ConnHooksAccessor) dataSource.getConnHooks()).onGet();
ConnHolder connHolder = null;
long[] waitedNanos = NO_WAIT;
SQLException sqlException = null;
ViburDBCPException viburException = null;
try {
if (onGet.length > 0) {
waitedNanos = new long[1];
connHolder = timeoutMs > 0 ? poolService.tryTake(timeoutMs, MILLISECONDS, waitedNanos) : poolService.take(waitedNanos);
} else {
connHolder = timeoutMs > 0 ? poolService.tryTake(timeoutMs, MILLISECONDS) : poolService.take();
}
if (connHolder == null) {
// we were *not* able to obtain a connection from the pool
sqlException = createSQLException(onGet.length > 0 ? waitedNanos[0] : MILLISECONDS.toNanos(timeoutMs));
}
} catch (ViburDBCPException e) {
// thrown (indirectly) by the ConnectionFactory.create() methods
viburException = e;
// currently all such errors are treated as recoverable, i.e., can be retried
sqlException = e.unwrapSQLException();
} finally {
Connection rawConnection = connHolder != null ? connHolder.rawConnection() : null;
try {
for (Hook.GetConnection hook : onGet) {
hook.on(rawConnection, waitedNanos[0]);
}
} catch (SQLException e) {
sqlException = chainSQLException(sqlException, e);
}
}
if (viburException != null) {
// a recoverable error
throw viburException;
}
if (sqlException != null) {
// a non-recoverable error
throw sqlException;
}
// never null if we reach this point
return connHolder;
}
use of org.vibur.dbcp.pool.HookHolder.ConnHooksAccessor in project vibur-dbcp by vibur.
the class PoolOperations method createSQLException.
private SQLException createSQLException(long takenNanos) {
String poolName = getPoolName(dataSource);
if (poolService.isTerminated()) {
return new SQLException(format("Pool %s, the poolService is terminated.", poolName), SQLSTATE_POOL_CLOSED_ERROR);
}
Hook.GetConnectionTimeout[] onTimeout = ((ConnHooksAccessor) dataSource.getConnHooks()).onTimeout();
// someone else has interrupted us, so we do not clear the flag
boolean isInterrupted = Thread.currentThread().isInterrupted();
if (!isInterrupted && onTimeout.length > 0) {
TakenConnection[] takenConnections = dataSource.getTakenConnections();
for (Hook.GetConnectionTimeout hook : onTimeout) {
hook.on(takenConnections, takenNanos);
}
}
double takenMs = takenNanos * 0.000_001;
int intTakenMs = (int) Math.round(takenMs);
return !isInterrupted ? new SQLTimeoutException(format("Pool %s, couldn't obtain SQL connection within %.3f ms.", poolName, takenMs), SQLSTATE_TIMEOUT_ERROR, intTakenMs) : new SQLException(format("Pool %s, interrupted while getting SQL connection, waited for %.3f ms.", poolName, takenMs), SQLSTATE_INTERRUPTED_ERROR, intTakenMs);
}
Aggregations