{"record":{"id":"715852e1c6e903e3","repo":"apache/shardingsphere","slug":"releasesavepoint","errorCode":null,"errorMessage":"releaseSavepoint","messagePattern":"releaseSavepoint","errorType":"exception","errorClass":"SQLFeatureNotSupportedException","httpStatus":null,"severity":"error","filePath":"jdbc/src/main/java/org/apache/shardingsphere/driver/state/circuit/connection/CircuitBreakerConnection.java","lineNumber":124,"sourceCode":"    \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() {\n        return 0;\n    }\n    \n    @Override\n    public PreparedStatement prepareStatement(final String sql) {\n        return new CircuitBreakerPreparedStatement();\n    }\n    \n    @Override\n    public PreparedStatement prepareStatement(final String sql, final int resultSetType, final int resultSetConcurrency) {","sourceCodeStart":106,"sourceCodeEnd":142,"githubUrl":"https://github.com/apache/shardingsphere/blob/e952770a215630a3659c75d64369168cd3e26b82/jdbc/src/main/java/org/apache/shardingsphere/driver/state/circuit/connection/CircuitBreakerConnection.java#L106-L142","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Only release a savepoint if creation actually succeeded (null-check the Savepoint produced by the same live connection).","Recover the underlying database / close the circuit so genuine connections are returned.","Wrap releaseSavepoint in try/catch for SQLFeatureNotSupportedException during degraded-mode operation.","Drop savepoint-based checkpointing for code that must keep running through circuit-break events."],"exampleFix":"// before\nfinally {\n    conn.releaseSavepoint(sp);\n}\n\n// after\nSavepoint sp = null;\ntry {\n    sp = supportsSavepoints ? conn.setSavepoint() : null;\n    ...\n} finally {\n    if (null != sp) {\n        try { conn.releaseSavepoint(sp); } catch (final SQLFeatureNotSupportedException ignored) { }\n    }\n}","handlingStrategy":"try-catch","validationCode":"if (null != sp) {\n    try { conn.releaseSavepoint(sp); } catch (final SQLFeatureNotSupportedException ignored) { }\n}","typeGuard":null,"tryCatchPattern":"finally {\n    if (null != sp) {\n        try {\n            conn.releaseSavepoint(sp);\n        } catch (final SQLFeatureNotSupportedException ex) {\n            LOGGER.debug(\"savepoint release skipped: {}\", ex.getMessage());\n        }\n    }\n}","preventionTips":["Only release savepoints created by the same, still-healthy connection.","Keep cleanup code exception-tolerant during degraded/circuit-broken states.","Never cache Savepoint objects across connection failures."],"tags":["jdbc","circuit-breaker","savepoint","cleanup"],"backgroundTag":null,"analyzedSha":"e952770a215630a3659c75d64369168cd3e26b82","analyzedAt":"2026-08-14T13:54:53.392Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}