apache/shardingsphere · error · SQLFeatureNotSupportedException

setSavepoint

Error message

setSavepoint

What it means

When ShardingSphere's driver-side circuit breaker is OPEN, Connection objects of type CircuitBreakerConnection keep the JDBC surface alive with no-op or stubbed methods, but setSavepoint() deliberately throws SQLFeatureNotSupportedException("setSavepoint") because creating a savepoint on a dead backend is meaningless. Seeing this exception means savepoint code ran during a circuit-broken state rather than on a healthy connection.

Source

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

        return false;
    }
    
    @Override
    public void commit() {
    }
    
    @Override
    public void rollback() {
    }
    
    @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() {

View on GitHub (pinned to e952770a21)

Solutions

  1. Guard savepoint creation with connection.getMetaData().supportsSavepoints() plus a circuit-state check, and fall back to a plain transaction.
  2. Fix the outage / re-enable the data source so the circuit closes and real connections are handed out again.
  3. Eliminate PROPAGATION_NESTED or savepoint checkpoints from code paths that must survive failover.
  4. Catch SQLFeatureNotSupportedException around setSavepoint and treat it as 'must roll back whole transaction'.

Example fix

// before
Savepoint sp = conn.setSavepoint();

// after
Savepoint sp = null;
try {
    if (conn.getMetaData().supportsSavepoints()) {
        sp = conn.setSavepoint();
    }
} catch (final SQLFeatureNotSupportedException ignored) {
    // circuit-broken or unsupported: run without savepoint
}
Defensive patterns

Strategy: validation

Validate before calling

boolean canSavepoint = false;
try {
    canSavepoint = conn.getMetaData().supportsSavepoints();
} catch (final SQLException ignored) { }
Savepoint sp = canSavepoint ? conn.setSavepoint() : null;

Try / catch

try {
    sp = conn.setSavepoint();
} catch (final SQLFeatureNotSupportedException ex) {
    // circuit-broken: run without partial-rollback capability
}

Prevention

When it happens

Trigger: Calling Connection.setSavepoint() on a connection obtained from a data source whose circuit breaker has opened (database unreachable or a 'circuit break' / lock-data-source operation executed).

Common situations: Spring nested transactions (PROPAGATION_NESTED) during a backend outage; batch frameworks that checkpoint work with savepoints; tests that exercise transaction APIs against a disabled data source.

Related errors


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