apache/shardingsphere · error · SQLFeatureNotSupportedException

releaseSavepoint

Error message

releaseSavepoint

What it means

On a circuit-broken ShardingSphere data source, releaseSavepoint(Savepoint) throws SQLFeatureNotSupportedException because no savepoint could ever have been created (setSavepoint also throws), so releasing one indicates application logic still running against the dead-connection stub. commit()/rollback() are silent no-ops in this state, making releaseSavepoint one of the few visible failures.

Source

Thrown at jdbc/src/main/java/org/apache/shardingsphere/driver/state/circuit/connection/CircuitBreakerConnection.java:124

    
    @Override
    public void rollback(final Savepoint savepoint) throws SQLException {
        throw new SQLFeatureNotSupportedException("rollback savepoint");
    }
    
    @Override
    public Savepoint setSavepoint() throws SQLException {
        throw new SQLFeatureNotSupportedException("setSavepoint");
    }
    
    @Override
    public Savepoint setSavepoint(final String name) throws SQLException {
        throw new SQLFeatureNotSupportedException("setSavepoint name");
    }
    
    @Override
    public void releaseSavepoint(final Savepoint savepoint) throws SQLException {
        throw new SQLFeatureNotSupportedException("releaseSavepoint");
    }
    
    @Override
    public void setHoldability(final int holdability) {
    }
    
    @Override
    public int getHoldability() {
        return 0;
    }
    
    @Override
    public PreparedStatement prepareStatement(final String sql) {
        return new CircuitBreakerPreparedStatement();
    }
    
    @Override
    public PreparedStatement prepareStatement(final String sql, final int resultSetType, final int resultSetConcurrency) {

View on GitHub (pinned to e952770a21)

Solutions

  1. Only release a savepoint if creation actually succeeded (null-check the Savepoint produced by the same live connection).
  2. Recover the underlying database / close the circuit so genuine connections are returned.
  3. Wrap releaseSavepoint in try/catch for SQLFeatureNotSupportedException during degraded-mode operation.
  4. Drop savepoint-based checkpointing for code that must keep running through circuit-break events.

Example fix

// before
finally {
    conn.releaseSavepoint(sp);
}

// after
Savepoint sp = null;
try {
    sp = supportsSavepoints ? conn.setSavepoint() : null;
    ...
} finally {
    if (null != sp) {
        try { conn.releaseSavepoint(sp); } catch (final SQLFeatureNotSupportedException ignored) { }
    }
}
Defensive patterns

Strategy: try-catch

Validate before calling

if (null != sp) {
    try { conn.releaseSavepoint(sp); } catch (final SQLFeatureNotSupportedException ignored) { }
}

Try / catch

finally {
    if (null != sp) {
        try {
            conn.releaseSavepoint(sp);
        } catch (final SQLFeatureNotSupportedException ex) {
            LOGGER.debug("savepoint release skipped: {}", ex.getMessage());
        }
    }
}

Prevention

When it happens

Trigger: Calling conn.releaseSavepoint(sp) — usually in a finally block after setSavepoint previously threw, or with a Savepoint object held from before the circuit opened — on a CircuitBreakerConnection.

Common situations: finally { if (sp != null) conn.releaseSavepoint(sp); } cleanup code executing during an outage; transaction-template code that releases checkpoints even when creation failed; failover tests that keep using stale Connection objects.

Related errors


AI-assisted analysis of apache/shardingsphere@e952770a21 (2026-08-14). Data as JSON: /api/errors/715852e1c6e903e3. Report an issue: GitHub.