Search in sources :

Example 1 with ConnHooksAccessor

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;
}
Also used : ViburDBCPException(org.vibur.dbcp.ViburDBCPException) SQLException(java.sql.SQLException) JdbcUtils.chainSQLException(org.vibur.dbcp.util.JdbcUtils.chainSQLException) ConnHooksAccessor(org.vibur.dbcp.pool.HookHolder.ConnHooksAccessor) Proxy.newProxyConnection(org.vibur.dbcp.proxy.Proxy.newProxyConnection) Connection(java.sql.Connection)

Example 2 with ConnHooksAccessor

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);
}
Also used : SQLException(java.sql.SQLException) JdbcUtils.chainSQLException(org.vibur.dbcp.util.JdbcUtils.chainSQLException) ConnHooksAccessor(org.vibur.dbcp.pool.HookHolder.ConnHooksAccessor) SQLTimeoutException(java.sql.SQLTimeoutException)

Aggregations

SQLException (java.sql.SQLException)2 ConnHooksAccessor (org.vibur.dbcp.pool.HookHolder.ConnHooksAccessor)2 JdbcUtils.chainSQLException (org.vibur.dbcp.util.JdbcUtils.chainSQLException)2 Connection (java.sql.Connection)1 SQLTimeoutException (java.sql.SQLTimeoutException)1 ViburDBCPException (org.vibur.dbcp.ViburDBCPException)1 Proxy.newProxyConnection (org.vibur.dbcp.proxy.Proxy.newProxyConnection)1