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

  1. Replace the JDBC driver with a version/database that supports savepoints (verify via connection.getMetaData().supportsSavepoints()).
  2. If the database truly cannot support savepoints, accept the semantics: keep the warning and understand row-level failures trigger full transaction rollback.
  3. Disable row-error handling if full rollback semantics are unacceptable, so no savepoint path is attempted.
  4. 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

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


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)