t8y2/dbx · error · SQLFeatureNotSupportedException

This JDBC driver does not support transactions

Error message

This JDBC driver does not support transactions

What it means

After opening the connection, beginManualTransaction queries DatabaseMetaData.supportsTransactions(). If metadata explicitly reports false (not null/unknown), it throws SQLFeatureNotSupportedException because setAutoCommit(false) and manual commits would be meaningless. This is a capability check driven by the driver's own metadata.

Source

Thrown at plugins/jdbc/src/main/java/app/dbx/jdbc/DbxJdbcPlugin.java:1050

            result.set("columns", columns);
            result.set("rows", rows);
            result.put("affected_rows", columns.isEmpty() ? Math.max(executed.updateCount(), 0) : 0);
            result.put("execution_time_ms", (System.nanoTime() - start) / 1_000_000);
            result.put("truncated", truncated);
            return result;
        }
    }

    private static ObjectNode beginManualTransaction(JsonNode connection, String database, String schema)
        throws SQLException {
        if (manualTransactionActive) {
            throw new SQLException("A manual transaction is already active");
        }
        Connection conn = openConnection(connection);
        DatabaseMetaData metadata = readMetadata(conn::getMetaData);
        Boolean supportsTransactions = metadata == null ? null : readMetadata(metadata::supportsTransactions);
        if (Boolean.FALSE.equals(supportsTransactions)) {
            throw new SQLFeatureNotSupportedException("This JDBC driver does not support transactions");
        }
        applyExecutionContext(connection, conn, database, schema);
        conn.setAutoCommit(false);
        manualTransactionActive = true;
        return okResult();
    }

    private static JsonNode executeInManualTransaction(
        JsonNode connection,
        String sql,
        String database,
        String schema,
        int maxRows,
        int fetchSize,
        int rowOffset,
        int timeoutSecs
    ) throws Exception {
        Connection conn = activeManualTransactionConnection(connection);

View on GitHub (pinned to c0390bff16)

Solutions

  1. Switch to a database with real transaction support (PostgreSQL, MySQL/InnoDB, SQLite, etc.) for workloads needing atomicity.
  2. If the backend does support transactions but the driver misreports it, use the vendor's official driver instead of a bridge/wrapper.
  3. Remove manual-transaction usage for this connection and rely on autocommit semantics.
  4. Verify with a direct JDBC snippet: conn.getMetaData().supportsTransactions() to confirm the capability before debugging the plugin.

Example fix

// before
beginTx(connCfg);   // driver: flat-file JDBC bridge -> SQLFeatureNotSupportedException
// after
// run statements in autocommit mode; no manual transaction
exec(connCfg, sql);
Defensive patterns

Strategy: validation

Validate before calling

// Java: capability check before beginning a manual transaction
java.sql.Connection c = /* open via plain JDBC */;
boolean ok = c.getMetaData().supportsTransactions();
c.close();
if (!ok) throw new IllegalStateException("backend does not support transactions; skip manual tx");

Try / catch

try {
    plugin.beginManualTransaction(connCfg);
} catch (java.sql.SQLFeatureNotSupportedException e) {
    // fall back to autocommit execution
    plugin.execute(connCfg, statements);
    return;
}

Prevention

When it happens

Trigger: Beginning a manual transaction against a database/driver that declares supportsTransactions() == false — e.g. certain lightweight embedded engines, CSV/flat-file JDBC bridges, or read-only proxy drivers.

Common situations: Pointing the plugin at a non-transactional store via a minimal JDBC driver, using a wrapper driver that reports capabilities incorrectly, or testing against an in-memory/flat-file backend.

Related errors


AI-assisted analysis of t8y2/dbx@c0390bff16 (2026-09-05). Data as JSON: /api/errors/2ef47c53f814b0ef. Report an issue: GitHub.