apache/seatunnel · warning
JDBC driver does not support savepoints. Row-error handling…
Error message
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={} What it means
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.
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.
Example fix
// before (warning observed)
log.warn("JDBC driver does not support savepoints. ... table={}", sinkTablePath);
// after (verify driver capability before enabling row-error handling)
if (connection.getMetaData().supportsSavepoints()) {
enableRowErrorHandlingWithSavepoints(connection);
} else {
log.warn("Falling back to full-transaction rollback semantics; table={}", sinkTablePath);
} Defensive patterns
Strategy: fallback
Validate before calling
try (Connection c = ds.getConnection()) {
boolean ok = c.getMetaData().supportsSavepoints();
if (!ok) log.warn("Driver lacks savepoints; row-error handling will use full rollback");
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- TRANSACTION_OPERATION_FAILED
- Failed to finish the JDBC source read transaction. Closing…
- Failed to get the JDBC source connection from the current…
- formatErrorMessage(action, xid, errorCode, errorMessage)
- [Instance ] Failed to clean up during abort
AI-assisted analysis of apache/seatunnel@cf67b549a7 (2026-09-10).
Data as JSON: /api/errors/2242124e5a5cc758.
Report an issue: GitHub.
Appendix: source
Thrown at seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/sink/JdbcSinkWriter.java:427
}
try {
DatabaseMetaData metaData = connectionProvider.getConnection().getMetaData();
supportsSavepoints = metaData != null && metaData.supportsSavepoints();
} catch (SQLException e) {
supportsSavepoints = false;
log.warn(
"Failed to check JDBC savepoint support; fallback to full transaction rollback.",
e);
}
return supportsSavepoints;
}
private void logSavepointUnsupported() {
if (savepointUnsupportedLogged) {
return;
}
savepointUnsupportedLogged = true;
log.warn(
"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={}",
sinkTablePath);
}
// Releasing an old savepoint is a best-effort cleanup. Some drivers invalidate savepoints after
// rollback/commit and should not fail the writer just because cleanup is no longer possible.
private void releaseSavepointSilently(Connection connection, Savepoint savepoint) {
if (savepoint == null) {
return;
}
try {
connection.releaseSavepoint(savepoint);
} catch (SQLException e) {
log.debug("Failed to release JDBC savepoint after moving row-error batch boundary.", e);
}
}View on GitHub (pinned to cf67b549a7)