apache/seatunnel · warning

Failed to close the JDBC source connection after transaction

Error message

Failed to close the JDBC source connection after transaction cleanup failed.

What it means

JdbcInputFormat.discardConnection() closes a connection after transaction cleanup already failed. If connection.close() itself throws, the close exception is attached as suppressed to the original cleanup exception and this warning logs both, then the finally block clears the provider's cached reference and retries close via chunkSplitter. It indicates the JDBC connection could not be cleanly released.

Source

Thrown at seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/internal/JdbcInputFormat.java:225

            finishReadTransaction(connection, configuredAutoCommit);
        } catch (SQLException e) {
            LOG.warn(
                    "Failed to finish the JDBC source read transaction. "
                            + "Closing the connection to avoid leaving or reusing an idle "
                            + "transaction.",
                    e);
            discardConnection(connection, e);
        }
    }

    private void discardConnection(Connection connection, SQLException cleanupException) {
        try {
            if (connection != null) {
                connection.close();
            }
        } catch (SQLException closeException) {
            cleanupException.addSuppressed(closeException);
            LOG.warn(
                    "Failed to close the JDBC source connection after transaction cleanup failed.",
                    cleanupException);
        } finally {
            // Clear the provider's cached reference and retry close for drivers whose first close
            // attempt failed.
            chunkSplitter.close();
        }
    }

    static void finishReadTransaction(Connection connection, boolean configuredAutoCommit)
            throws SQLException {
        if (connection == null || connection.isClosed()) {
            return;
        }

        boolean currentAutoCommit = connection.getAutoCommit();
        if (!currentAutoCommit) {
            // JDBC source reads do not have changes to commit. Rollback ends the server-side cursor

View on GitHub (pinned to cf67b549a7)

Solutions

  1. Inspect the suppressed exception and root cause; typically no action is required since the connection is discarded anyway.
  2. Fix the root connectivity issue (network, firewall idle resets, server timeouts) that killed the connection earlier.
  3. Upgrade the JDBC driver if close() throws spuriously on dead connections.
  4. Ensure the finalizer/provider retry (chunkSplitter.close()) releases the underlying resource; check for connection leaks in the driver's pool.

Example fix

// before
connection.close();
// after
try {
    if (connection != null && !connection.isClosed()) {
        connection.close();
    }
} catch (SQLException e) {
    LOG.warn("Discarding un-closable JDBC connection", e);
}
Defensive patterns

Strategy: try-catch

Validate before calling

if (conn != null && !conn.isClosed()) {
    // safe to attempt close
}

Try / catch

try {
    connection.close();
} catch (SQLException closeEx) {
    // treat as discarded; ensure pool/finalizer reclaims the resource
    LOG.debug("Connection close failed, discarded", closeEx);
}

Prevention

When it happens

Trigger: finishReadTransaction() -> discardConnection() when connection.close() throws SQLException — broken socket at close, driver that throws instead of swallowing close errors, or already-aborted connection.

Common situations: Server or network gone before job teardown; buggy drivers whose close() throws on dead sockets; resource warnings at job shutdown stacking with earlier transaction errors.

Related errors


AI-assisted analysis of apache/seatunnel@cf67b549a7 (2026-09-10). Data as JSON: /api/errors/0e84af644e08bee0. Report an issue: GitHub.