apache/dolphinscheduler · error · RegistryException

Release the lock: error

Error message

Release the lock:  error

What it means

Thrown by JdbcRegistryServer.releaseJdbcRegistryLock when the underlying JdbcRegistryLockManager fails to release a distributed lock held by the given client for the given lock key. The original exception is wrapped, so the cause carries the real reason (SQL failure, lock not owned, connection loss). It indicates the caller's lock release did not complete successfully.

Source

Thrown at dolphinscheduler-registry/dolphinscheduler-registry-plugins/dolphinscheduler-registry-jdbc/src/main/java/org/apache/dolphinscheduler/plugin/registry/jdbc/server/JdbcRegistryServer.java:253

            throw new RegistryException("Acquire the lock: " + lockKey + " error", ex);
        }
    }

    @Override
    public boolean acquireJdbcRegistryLock(Long clientId, String lockKey, long timeout) {
        try {
            return jdbcRegistryLockManager.acquireJdbcRegistryLock(clientId, lockKey, timeout);
        } catch (Exception ex) {
            throw new RegistryException("Acquire the lock: " + lockKey + " error", ex);
        }
    }

    @Override
    public void releaseJdbcRegistryLock(Long clientId, String lockKey) {
        try {
            jdbcRegistryLockManager.releaseJdbcRegistryLock(clientId, lockKey);
        } catch (Exception ex) {
            throw new RegistryException("Release the lock: " + lockKey + " error", ex);
        }
    }

    @Override
    public void close() {
        jdbcRegistryServerState = JdbcRegistryServerState.STOPPED;
        schedulerThreadExecutor.shutdown();
        List<Long> clientIds = jdbcRegistryClients.stream()
                .map(IJdbcRegistryClient::getJdbcRegistryClientIdentify)
                .map(JdbcRegistryClientIdentify::getClientId)
                .collect(Collectors.toList());
        doPurgeJdbcRegistryClientInDB(clientIds);
        jdbcRegistryClients.clear();
        jdbcRegistryClientDTOMap.clear();
    }

    private void purgeInvalidJdbcRegistryMetadata() {
        final StopWatch stopWatch = StopWatch.createStarted();

View on GitHub (pinned to 02eac45a1b)

Solutions

  1. Inspect the wrapped cause (getCause) to determine whether it is a SQL/connection failure or a non-existent/foreign lock row
  2. Verify the clientId and lockKey passed match exactly those returned when the lock was acquired
  3. Ensure the lock table exists and the datasource is healthy before shutdown
  4. Release the lock in a finally block only once, guarding against double release; on repeated failure log and let lock TTL expiry clean up
  5. Retry the release with backoff on transient SQL exceptions

Example fix

// before
registry.releaseJdbcRegistryLock(clientId, lockKey);
// after
try {
    registry.releaseJdbcRegistryLock(clientId, lockKey);
} catch (RegistryException e) {
    log.warn("Failed to release lock {}, will rely on TTL expiry: {}", lockKey, e.getCause());
}
Defensive patterns

Strategy: try-catch

Validate before calling

boolean lockOwned = jdbcRegistryLockManager.getLockThread(lockKey)
        .map(t -> Objects.equals(t.getClientId(), clientId)).orElse(false);
if (!lockOwned) throw new IllegalStateException("clientId does not own lock " + lockKey);

Type guard

boolean ownsLock(Long clientId, String lockKey) {
    return Optional.ofNullable(lockMap.get(lockKey))
        .map(entry -> Objects.equals(entry.getClientId(), clientId))
        .orElse(false);
}

Try / catch

try {
    registry.releaseJdbcRegistryLock(clientId, lockKey);
} catch (RegistryException e) {
    log.warn("Lock {} release failed; relying on TTL expiry", lockKey, e.getCause());
}

Prevention

When it happens

Trigger: Calling releaseJdbcRegistryLock(clientId, lockKey) when the clientId no longer owns the lock, the lock row was already deleted/expired, or the underlying database update/delete fails (connection error, deadlock, table missing).

Common situations: Database outage or connection-pool exhaustion during shutdown; lock TTL expired and was re-acquired by another client before release; double-release after an earlier session crash; schema not initialized (lock table absent).

Related errors


AI-assisted analysis of apache/dolphinscheduler@02eac45a1b (2026-09-06). Data as JSON: /api/errors/5a315d902b0bdb63. Report an issue: GitHub.