Search in sources :

Example 56 with SQLTimeoutException

use of java.sql.SQLTimeoutException in project spf4j by zolyfarkas.

the class JdbcSemaphore method tryAcquire.

@SuppressFBWarnings("UW_UNCOND_WAIT")
@CheckReturnValue
@Override
public boolean tryAcquire(final int nrPermits, final long deadlineNanos) throws InterruptedException {
    if (nrPermits < 1) {
        throw new IllegalArgumentException("You should try to acquire something! not " + nrPermits);
    }
    synchronized (syncObj) {
        boolean acquired = false;
        final MutableHolder<Boolean> beat = MutableHolder.of(Boolean.FALSE);
        do {
            checkClosed();
            validate();
            try {
                acquired = jdbc.transactOnConnection(new HandlerNano<Connection, Boolean, SQLException>() {

                    @Override
                    public Boolean handle(final Connection conn, final long deadlineNanos) throws SQLException {
                        try (PreparedStatement stmt = conn.prepareStatement(acquireSql)) {
                            stmt.setQueryTimeout(Math.min(JdbcTemplate.getTimeoutToDeadlineSeconds(deadlineNanos), jdbcTimeoutSeconds));
                            stmt.setInt(1, nrPermits);
                            stmt.setNString(2, org.spf4j.base.Runtime.PROCESS_ID);
                            stmt.setNString(3, semName);
                            stmt.setInt(4, nrPermits);
                            int rowsUpdated = stmt.executeUpdate();
                            Boolean acquired;
                            if (rowsUpdated == 1) {
                                try (PreparedStatement ostmt = conn.prepareStatement(acquireByOwnerSql)) {
                                    ostmt.setInt(1, nrPermits);
                                    ostmt.setNString(2, org.spf4j.base.Runtime.PROCESS_ID);
                                    ostmt.setNString(3, semName);
                                    ostmt.setQueryTimeout(Math.min(JdbcTemplate.getTimeoutToDeadlineSeconds(deadlineNanos), jdbcTimeoutSeconds));
                                    int nrUpdated = ostmt.executeUpdate();
                                    if (nrUpdated != 1) {
                                        throw new IllegalStateException("Updated " + nrUpdated + " is incorrect for " + ostmt);
                                    }
                                }
                                acquired = Boolean.TRUE;
                            } else {
                                if (rowsUpdated > 1) {
                                    throw new IllegalStateException("Too many rows updated! when trying to acquire " + nrPermits);
                                }
                                acquired = Boolean.FALSE;
                            }
                            long currNanoTime = TimeSource.nanoTime();
                            if (deadlineNanos - currNanoTime > heartBeat.getBeatDurationNanos()) {
                                // do a heartbeat if have time, and if it makes sense.
                                beat.setValue(heartBeat.tryBeat(conn, currNanoTime, deadlineNanos));
                            }
                            return acquired;
                        }
                    }
                }, deadlineNanos);
            } catch (SQLTimeoutException ex) {
                return false;
            } catch (SQLException ex) {
                throw new LockRuntimeException(ex);
            }
            if (beat.getValue()) {
                // we did a heartbeat as part of the acquisition.
                heartBeat.updateLastRunNanos(TimeSource.nanoTime());
            }
            if (!acquired) {
                long secondsLeft = JdbcTemplate.getTimeoutToDeadlineSecondsNoEx(deadlineNanos);
                if (secondsLeft < 0) {
                    return false;
                }
                if (secondsLeft < CLEANUP_TIMEOUT_SECONDS) {
                    Future<Integer> fut = DefaultExecutor.INSTANCE.submit(() -> removeDeadHeartBeatAndNotOwnerRows(CLEANUP_TIMEOUT_SECONDS));
                    try {
                        fut.get(secondsLeft, TimeUnit.SECONDS);
                    } catch (TimeoutException ex) {
                        // removing dead entries did not finish in time, but continues in the background.
                        break;
                    } catch (ExecutionException ex) {
                        throw new LockRuntimeException(ex);
                    }
                } else {
                    try {
                        removeDeadHeartBeatAndNotOwnerRows(secondsLeft);
                    } catch (SQLTimeoutException ex) {
                        return false;
                    } catch (SQLException ex) {
                        throw new LockRuntimeException(ex);
                    }
                }
                try {
                    if (releaseDeadOwnerPermits(nrPermits) <= 0) {
                        // wait of we did not find anything dead to release.
                        long wtimeMilis = Math.min(TimeUnit.NANOSECONDS.toMillis(deadlineNanos - TimeSource.nanoTime()), ThreadLocalRandom.current().nextLong(acquirePollMillis));
                        if (wtimeMilis > 0) {
                            syncObj.wait(wtimeMilis);
                        } else {
                            break;
                        }
                    }
                } catch (SQLException ex) {
                    throw new LockRuntimeException(ex);
                }
            }
        } while (!acquired && deadlineNanos > TimeSource.nanoTime());
        if (acquired) {
            ownedReservations += nrPermits;
        }
        return acquired;
    }
}
Also used : SQLException(java.sql.SQLException) Connection(java.sql.Connection) PreparedStatement(java.sql.PreparedStatement) HandlerNano(org.spf4j.base.HandlerNano) LockRuntimeException(org.spf4j.concurrent.LockRuntimeException) SQLTimeoutException(java.sql.SQLTimeoutException) ExecutionException(java.util.concurrent.ExecutionException) SQLTimeoutException(java.sql.SQLTimeoutException) TimeoutException(java.util.concurrent.TimeoutException) CheckReturnValue(javax.annotation.CheckReturnValue) SuppressFBWarnings(edu.umd.cs.findbugs.annotations.SuppressFBWarnings)

Aggregations

SQLTimeoutException (java.sql.SQLTimeoutException)56 SQLException (java.sql.SQLException)39 ResultSet (java.sql.ResultSet)20 Statement (java.sql.Statement)17 Connection (java.sql.Connection)15 Test (org.testng.annotations.Test)15 Test (org.junit.Test)14 BaseTest (util.BaseTest)14 PreparedStatement (java.sql.PreparedStatement)12 JdbcTest (org.apache.drill.categories.JdbcTest)8 SQLFeatureNotSupportedException (java.sql.SQLFeatureNotSupportedException)7 ArrayList (java.util.ArrayList)7 HadoopException (org.apache.ranger.plugin.client.HadoopException)6 ScreenCreator (org.apache.drill.exec.physical.impl.ScreenCreator)4 MessageEvent (org.cerberus.engine.entity.MessageEvent)4 SuppressFBWarnings (edu.umd.cs.findbugs.annotations.SuppressFBWarnings)3 TimeoutException (java.util.concurrent.TimeoutException)3 CoreMatchers.containsString (org.hamcrest.CoreMatchers.containsString)3 Ignore (org.junit.Ignore)3 IOException (java.io.IOException)2