{"record":{"id":"7c44ca6e064dcfc0","repo":"alibaba/spring-ai-alibaba","slug":"unable-to-release-checkpoint-7c44ca","errorCode":null,"errorMessage":"Unable to release checkpoint","messagePattern":"Unable to release checkpoint","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"spring-ai-alibaba-graph-core/src/main/java/com/alibaba/cloud/ai/graph/checkpoint/savers/postgresql/PostgresSaver.java","lineNumber":594,"sourceCode":"\t\tConnection conn = null;\n\t\ttry (Connection ignored = conn = getConnection()) {\n\t\t\tconn.setAutoCommit(false);\n\t\t\tlog.trace(\"Executing release Thread:\\n---\\n{}---\", RELEASE_THREAD);\n\t\t\ttry (PreparedStatement ps = conn.prepareStatement(RELEASE_THREAD)) {\n\t\t\t\tps.setString(1, threadId);\n\t\t\t\tint rowsAffected = ps.executeUpdate();\n\t\t\t\tif (rowsAffected == 0) {\n\t\t\t\t\tconn.rollback();\n\t\t\t\t\tthrow new IllegalStateException(format(\"Thread '%s' not found or already released\", threadId));\n\t\t\t\t}\n\t\t\t}\n\t\t\tconn.commit();\n\t\t\tlog.debug(\"Thread {} released successfully.\", threadId);\n\t\t}\n\t\tcatch (SQLException ex) {\n\t\t\tlog.error(\"Error releasing thread {}\", threadId, ex);\n\t\t\trollback(conn, threadId);\n\t\t\tthrow new Exception(\"Unable to release checkpoint\", ex);\n\t\t}\n\t}\n\n\t/**\n\t * Datasource connection\n\t *\n\t * @return Datasource connection\n\t * @throws SQLException exception\n\t */\n\tprotected Connection getConnection() throws SQLException {\n\t\treturn datasource.getConnection();\n\t}\n\n\t/**\n\t * A builder for PostgresSaver.\n\t */\n\tpublic static class Builder {\n\t\tpublic StateSerializer stateSerializer;","sourceCodeStart":576,"sourceCodeEnd":612,"githubUrl":"https://github.com/alibaba/spring-ai-alibaba/blob/f82da0b50f35744c13968191be2b1cd2452ef550/spring-ai-alibaba-graph-core/src/main/java/com/alibaba/cloud/ai/graph/checkpoint/savers/postgresql/PostgresSaver.java#L576-L612","documentation":"releaseThread wraps any SQLException during the release UPDATE/commit/rollback in a generic checked Exception with message 'Unable to release checkpoint', chaining the original SQL error. It signals the database operation to release a thread lock failed at the JDBC level.","triggerScenarios":"Any SQLException thrown by conn.prepareStatement(RELEASE_THREAD), executeUpdate(), commit() or rollback() inside releaseThread — e.g. connection dropped, table missing, lock timeout, serialization failure.","commonSituations":"Postgres restart or network blip mid-transaction; missing checkpoints schema/table after migration; insufficient privileges on the table; connection pool returning a closed connection.","solutions":["Inspect the chained cause (getCause()) SQLException for the real JDBC error code and message.","Retry releaseThread with a fresh connection if the cause indicates a transient connection/serialization failure.","Verify the checkpoint schema/tables exist and the DB user has UPDATE privileges.","Validate connection pool health and Postgres connectivity (network, firewall, SSL)."],"exampleFix":"// before\ntry { saver.releaseThread(conn, id); }\ncatch (Exception e) { e.printStackTrace(); }\n// after\ntry { saver.releaseThread(conn, id); }\ncatch (Exception e) {\n    Throwable cause = e.getCause();\n    if (cause instanceof SQLException sqlEx && sqlEx.getSQLState().startsWith(\"08\")) {\n        // transient connection issue: retry with new connection\n    } else {\n        throw e;\n    }\n}","handlingStrategy":"retry","validationCode":"// verify connectivity before releasing\ntry (Connection c = ds.getConnection()) { assert c.isValid(2); }","typeGuard":null,"tryCatchPattern":"try { saver.releaseThread(conn, id); } catch (Exception e) { Throwable c = e.getCause(); if (c instanceof SQLException se && se.getSQLState().startsWith(\"08\")) retryWithBackoff(); else throw e; }","preventionTips":["Use a healthy connection pool with validation queries","Monitor Postgres availability","Check schema/privileges at startup","Log the chained SQLException cause"],"tags":["postgresql","jdbc","checkpoint","database"],"backgroundTag":"database-write-failed","analyzedSha":"f82da0b50f35744c13968191be2b1cd2452ef550","analyzedAt":"2026-09-09T15:32:42.421Z","contentChangedAt":"2026-09-09T15:32:42.421Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}