{"record":{"id":"a1948f7c305657ee","repo":"apache/iceberg","slug":"interrupted-during-trylock","errorCode":null,"errorMessage":"Interrupted during tryLock","messagePattern":"Interrupted during tryLock","errorType":"exception","errorClass":"UncheckedInterruptedException","httpStatus":null,"severity":"warning","filePath":"flink/v1.20/flink/src/main/java/org/apache/iceberg/flink/maintenance/api/JdbcLockFactory.java","lineNumber":199,"sourceCode":"      try {\n        return pool.run(\n            conn -> {\n              try (PreparedStatement sql = conn.prepareStatement(CREATE_LOCK_SQL)) {\n                sql.setString(1, type.key);\n                sql.setString(2, lockId);\n                sql.setString(3, newInstanceId);\n                int count = sql.executeUpdate();\n                LOG.info(\n                    \"Created {} lock with instanceId {} with row count {}\",\n                    this,\n                    newInstanceId,\n                    count);\n                return count == 1;\n              }\n            });\n      } catch (InterruptedException e) {\n        Thread.currentThread().interrupt();\n        throw new UncheckedInterruptedException(e, \"Interrupted during tryLock\");\n      } catch (SQLException e) {\n        // SQL exception happened when creating the lock. Check if the lock creation was\n        // successful behind the scenes.\n        if (newInstanceId.equals(instanceId())) {\n          return true;\n        } else {\n          throw new UncheckedSQLException(e, \"Failed to create %s lock\", this);\n        }\n      }\n    }\n\n    @SuppressWarnings(\"checkstyle:NestedTryDepth\")\n    @Override\n    public boolean isHeld() {\n      try {\n        return pool.run(\n            conn -> {\n              try (PreparedStatement sql = conn.prepareStatement(GET_LOCK_SQL)) {","sourceCodeStart":181,"sourceCodeEnd":217,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/flink/v1.20/flink/src/main/java/org/apache/iceberg/flink/maintenance/api/JdbcLockFactory.java#L181-L217","documentation":"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.","triggerScenarios":"Calling tryLock on the JdbcLock while the executing thread is interrupted (task cancel, failover) during the pooled INSERT statement.","commonSituations":"Job cancellation/restart concurrent with lock acquisition; slow lock INSERT due to DB contention makes the interruption window wider.","solutions":["If interruption is intentional cancellation, accept the error and shut down cleanly.","If spurious, inspect the interrupt source (cancel thread, watchdog) and ensure it doesn't fire during startup.","Reduce DB latency/lock contention so tryLock completes quickly.","Retry acquiring the lock after the job restarts; the lock row state is consistent because instance IDs are checked."],"exampleFix":"// operational: avoid cancelling during acquisition; or configure retry on the trigger\n.option(\"trigger.lock.retry-delay\", \"5 s\")","handlingStrategy":"try-catch","validationCode":"// check lock state before acquiring\nif (lock.isHeld() && !lock.isHeldByCurrentInstance()) {\n    throw new IllegalStateException(\"Lock already held by another instance\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    acquired = lock.tryLock();\n} catch (UncheckedInterruptedException e) {\n    Thread.currentThread().interrupt();\n    throw e; // treat as cancellation\n}","preventionTips":["Avoid task cancellation during lock acquisition","Configure trigger lock retry delays to smooth over transient failures","Keep lock INSERT latency low via DB tuning","On restart, rely on instance-ID checking for consistent recovery"],"tags":["jdbc","flink","interrupted","lock","cancellation"],"backgroundTag":"thread-interrupted","analyzedSha":"86d9c8fc543e7c56c9f624eb725f76c9baff9570","analyzedAt":"2026-09-12T00:46:39.097Z","contentChangedAt":"2026-09-12T00:46:39.097Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}