{"record":{"id":"671b399ac91f7eb1","repo":"apache/shardingsphere","slug":"setsavepoint","errorCode":null,"errorMessage":"setSavepoint","messagePattern":"setSavepoint","errorType":"exception","errorClass":"SQLFeatureNotSupportedException","httpStatus":null,"severity":"error","filePath":"jdbc/src/main/java/org/apache/shardingsphere/driver/state/circuit/connection/CircuitBreakerConnection.java","lineNumber":114,"sourceCode":"        return false;\n    }\n    \n    @Override\n    public void commit() {\n    }\n    \n    @Override\n    public void rollback() {\n    }\n    \n    @Override\n    public void rollback(final Savepoint savepoint) throws SQLException {\n        throw new SQLFeatureNotSupportedException(\"rollback savepoint\");\n    }\n    \n    @Override\n    public Savepoint setSavepoint() throws SQLException {\n        throw new SQLFeatureNotSupportedException(\"setSavepoint\");\n    }\n    \n    @Override\n    public Savepoint setSavepoint(final String name) throws SQLException {\n        throw new SQLFeatureNotSupportedException(\"setSavepoint name\");\n    }\n    \n    @Override\n    public void releaseSavepoint(final Savepoint savepoint) throws SQLException {\n        throw new SQLFeatureNotSupportedException(\"releaseSavepoint\");\n    }\n    \n    @Override\n    public void setHoldability(final int holdability) {\n    }\n    \n    @Override\n    public int getHoldability() {","sourceCodeStart":96,"sourceCodeEnd":132,"githubUrl":"https://github.com/apache/shardingsphere/blob/e952770a215630a3659c75d64369168cd3e26b82/jdbc/src/main/java/org/apache/shardingsphere/driver/state/circuit/connection/CircuitBreakerConnection.java#L96-L132","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","solutions":["Guard savepoint creation with connection.getMetaData().supportsSavepoints() plus a circuit-state check, and fall back to a plain transaction.","Fix the outage / re-enable the data source so the circuit closes and real connections are handed out again.","Eliminate PROPAGATION_NESTED or savepoint checkpoints from code paths that must survive failover.","Catch SQLFeatureNotSupportedException around setSavepoint and treat it as 'must roll back whole transaction'."],"exampleFix":"// before\nSavepoint sp = conn.setSavepoint();\n\n// after\nSavepoint sp = null;\ntry {\n    if (conn.getMetaData().supportsSavepoints()) {\n        sp = conn.setSavepoint();\n    }\n} catch (final SQLFeatureNotSupportedException ignored) {\n    // circuit-broken or unsupported: run without savepoint\n}","handlingStrategy":"validation","validationCode":"boolean canSavepoint = false;\ntry {\n    canSavepoint = conn.getMetaData().supportsSavepoints();\n} catch (final SQLException ignored) { }\nSavepoint sp = canSavepoint ? conn.setSavepoint() : null;","typeGuard":null,"tryCatchPattern":"try {\n    sp = conn.setSavepoint();\n} catch (final SQLFeatureNotSupportedException ex) {\n    // circuit-broken: run without partial-rollback capability\n}","preventionTips":["Capability-check supportsSavepoints() once per connection, not per statement.","Design transaction boundaries so a full rollback is always an acceptable outcome.","Alert on circuit-breaker OPEN events so savepoint failures are expected, not mysterious."],"tags":["jdbc","circuit-breaker","savepoint"],"backgroundTag":null,"analyzedSha":"e952770a215630a3659c75d64369168cd3e26b82","analyzedAt":"2026-08-14T13:54:53.392Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}