{"record":{"id":"2242124e5a5cc758","repo":"apache/seatunnel","slug":"jdbc-driver-does-not-support-savepoints-row-error","errorCode":null,"errorMessage":"JDBC driver does not support savepoints. Row-error handling will keep auto-flushed rows pending until checkpoint commit and fall back to full transaction rollback on row-level write failure. table={}","messagePattern":"JDBC driver does not support savepoints\\. Row-error handling will keep auto-flushed rows pending until checkpoint commit and fall back to full transaction rollback on row-level write failure\\. table=(.+?)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/sink/JdbcSinkWriter.java","lineNumber":427,"sourceCode":"        }\n        try {\n            DatabaseMetaData metaData = connectionProvider.getConnection().getMetaData();\n            supportsSavepoints = metaData != null && metaData.supportsSavepoints();\n        } catch (SQLException e) {\n            supportsSavepoints = false;\n            log.warn(\n                    \"Failed to check JDBC savepoint support; fallback to full transaction rollback.\",\n                    e);\n        }\n        return supportsSavepoints;\n    }\n\n    private void logSavepointUnsupported() {\n        if (savepointUnsupportedLogged) {\n            return;\n        }\n        savepointUnsupportedLogged = true;\n        log.warn(\n                \"JDBC driver does not support savepoints. Row-error handling will keep \"\n                        + \"auto-flushed rows pending until checkpoint commit and fall back to full \"\n                        + \"transaction rollback on row-level write failure. table={}\",\n                sinkTablePath);\n    }\n\n    // Releasing an old savepoint is a best-effort cleanup. Some drivers invalidate savepoints after\n    // rollback/commit and should not fail the writer just because cleanup is no longer possible.\n    private void releaseSavepointSilently(Connection connection, Savepoint savepoint) {\n        if (savepoint == null) {\n            return;\n        }\n        try {\n            connection.releaseSavepoint(savepoint);\n        } catch (SQLException e) {\n            log.debug(\"Failed to release JDBC savepoint after moving row-error batch boundary.\", e);\n        }\n    }","sourceCodeStart":409,"sourceCodeEnd":445,"githubUrl":"https://github.com/apache/seatunnel/blob/cf67b549a7a6c35fa0beb12d83c62892427ea919/seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/sink/JdbcSinkWriter.java#L409-L445","documentation":"JdbcSinkWriter logs this warning once when the underlying JDBC driver's DatabaseMetaData.supportsSavepoints() returns false. Without savepoints, the connector cannot roll back only rows written after the last auto-flush boundary, so on a row-level write failure it must roll back the entire transaction and keep auto-flushed rows pending until the checkpoint commit finalizes them.","triggerScenarios":"markSuccessfulAutoFlushBoundaryIfNeeded calls logSavepointUnsupported when row-error handling is enabled (allowing row-level error recovery) and the Connection's metadata reports savepoints unsupported; happens at most once per writer instance.","commonSituations":"Using JDBC drivers that lack savepoint support (e.g. some OLAP/wire-protocol drivers, ClickHouse, older Hive/Phoenix drivers); running with XA disabled or in autoCommit-unfriendly databases while relying on error-tolerance features.","solutions":["Replace the JDBC driver with a version/database that supports savepoints (verify via connection.getMetaData().supportsSavepoints()).","If the database truly cannot support savepoints, accept the semantics: keep the warning and understand row-level failures trigger full transaction rollback.","Disable row-error handling if full rollback semantics are unacceptable, so no savepoint path is attempted.","Check that the correct JDBC URL/driver class is used — connecting with a generic/generic-compat driver instead of the native one may drop savepoint support."],"exampleFix":"// before (warning observed)\nlog.warn(\"JDBC driver does not support savepoints. ... table={}\", sinkTablePath);\n// after (verify driver capability before enabling row-error handling)\nif (connection.getMetaData().supportsSavepoints()) {\n    enableRowErrorHandlingWithSavepoints(connection);\n} else {\n    log.warn(\"Falling back to full-transaction rollback semantics; table={}\", sinkTablePath);\n}","handlingStrategy":"fallback","validationCode":"try (Connection c = ds.getConnection()) {\n    boolean ok = c.getMetaData().supportsSavepoints();\n    if (!ok) log.warn(\"Driver lacks savepoints; row-error handling will use full rollback\");\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Verify supportsSavepoints() on the target driver before enabling row-error handling","Use native, current-version JDBC drivers rather than generic bridges","Read driver docs on transaction/savepoint support for OLAP databases"],"tags":["jdbc","savepoints","transaction","checkpoint"],"backgroundTag":"unsupported-operation","analyzedSha":"cf67b549a7a6c35fa0beb12d83c62892427ea919","analyzedAt":"2026-09-10T21:44:55.265Z","contentChangedAt":"2026-09-10T21:44:55.265Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}