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
- Inspect the wrapped cause (getCause) to determine whether it is a SQL/connection failure or a non-existent/foreign lock row
- Verify the clientId and lockKey passed match exactly those returned when the lock was acquired
- Ensure the lock table exists and the datasource is healthy before shutdown
- Release the lock in a finally block only once, guarding against double release; on repeated failure log and let lock TTL expiry clean up
- 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
- Only release locks with the clientId/key pair returned at acquisition
- Wrap release in finally exactly once to avoid double release
- Verify the lock table exists and the DB connection pool is healthy before shutdown
- Rely on lock TTL expiry as a fallback and log release failures
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
- Get key: %s error
- Check key: %s exist error
- Acquire lock: %s error
- Acquire the lock: error
- no master server available
AI-assisted analysis of apache/dolphinscheduler@02eac45a1b (2026-09-06).
Data as JSON: /api/errors/5a315d902b0bdb63.
Report an issue: GitHub.