apache/iceberg · warning · UncheckedInterruptedException

Interrupted during tryLock

Error message

Interrupted during tryLock

What it means

JdbcLock.tryLock performs an INSERT to claim the lock row through the connection pool. If the thread is interrupted during that call, the interrupt flag is restored and UncheckedInterruptedException is thrown; a plain SQLException instead triggers a fallback check whether the lock row was created anyway.

Source

Thrown at flink/v1.20/flink/src/main/java/org/apache/iceberg/flink/maintenance/api/JdbcLockFactory.java:199

      try {
        return pool.run(
            conn -> {
              try (PreparedStatement sql = conn.prepareStatement(CREATE_LOCK_SQL)) {
                sql.setString(1, type.key);
                sql.setString(2, lockId);
                sql.setString(3, newInstanceId);
                int count = sql.executeUpdate();
                LOG.info(
                    "Created {} lock with instanceId {} with row count {}",
                    this,
                    newInstanceId,
                    count);
                return count == 1;
              }
            });
      } catch (InterruptedException e) {
        Thread.currentThread().interrupt();
        throw new UncheckedInterruptedException(e, "Interrupted during tryLock");
      } catch (SQLException e) {
        // SQL exception happened when creating the lock. Check if the lock creation was
        // successful behind the scenes.
        if (newInstanceId.equals(instanceId())) {
          return true;
        } else {
          throw new UncheckedSQLException(e, "Failed to create %s lock", this);
        }
      }
    }

    @SuppressWarnings("checkstyle:NestedTryDepth")
    @Override
    public boolean isHeld() {
      try {
        return pool.run(
            conn -> {
              try (PreparedStatement sql = conn.prepareStatement(GET_LOCK_SQL)) {

View on GitHub (pinned to 86d9c8fc54)

Solutions

  1. If interruption is intentional cancellation, accept the error and shut down cleanly.
  2. If spurious, inspect the interrupt source (cancel thread, watchdog) and ensure it doesn't fire during startup.
  3. Reduce DB latency/lock contention so tryLock completes quickly.
  4. Retry acquiring the lock after the job restarts; the lock row state is consistent because instance IDs are checked.

Example fix

// operational: avoid cancelling during acquisition; or configure retry on the trigger
.option("trigger.lock.retry-delay", "5 s")
Defensive patterns

Strategy: try-catch

Validate before calling

// check lock state before acquiring
if (lock.isHeld() && !lock.isHeldByCurrentInstance()) {
    throw new IllegalStateException("Lock already held by another instance");
}

Try / catch

try {
    acquired = lock.tryLock();
} catch (UncheckedInterruptedException e) {
    Thread.currentThread().interrupt();
    throw e; // treat as cancellation
}

Prevention

When it happens

Trigger: Calling tryLock on the JdbcLock while the executing thread is interrupted (task cancel, failover) during the pooled INSERT statement.

Common situations: Job cancellation/restart concurrent with lock acquisition; slow lock INSERT due to DB contention makes the interruption window wider.

Related errors


AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12). Data as JSON: /api/errors/a1948f7c305657ee. Report an issue: GitHub.