{"record":{"id":"8d8aebe3aba5112f","repo":"t8y2/dbx","slug":"a-manual-transaction-is-already-active","errorCode":null,"errorMessage":"A manual transaction is already active","messagePattern":"A manual transaction is already active","errorType":"exception","errorClass":"SQLException","httpStatus":null,"severity":"error","filePath":"plugins/jdbc/src/main/java/app/dbx/jdbc/DbxJdbcPlugin.java","lineNumber":1044,"sourceCode":"                        }\n                        rows.add(row);\n                    }\n                }\n            }\n\n            result.set(\"columns\", columns);\n            result.set(\"rows\", rows);\n            result.put(\"affected_rows\", columns.isEmpty() ? Math.max(executed.updateCount(), 0) : 0);\n            result.put(\"execution_time_ms\", (System.nanoTime() - start) / 1_000_000);\n            result.put(\"truncated\", truncated);\n            return result;\n        }\n    }\n\n    private static ObjectNode beginManualTransaction(JsonNode connection, String database, String schema)\n        throws SQLException {\n        if (manualTransactionActive) {\n            throw new SQLException(\"A manual transaction is already active\");\n        }\n        Connection conn = openConnection(connection);\n        DatabaseMetaData metadata = readMetadata(conn::getMetaData);\n        Boolean supportsTransactions = metadata == null ? null : readMetadata(metadata::supportsTransactions);\n        if (Boolean.FALSE.equals(supportsTransactions)) {\n            throw new SQLFeatureNotSupportedException(\"This JDBC driver does not support transactions\");\n        }\n        applyExecutionContext(connection, conn, database, schema);\n        conn.setAutoCommit(false);\n        manualTransactionActive = true;\n        return okResult();\n    }\n\n    private static JsonNode executeInManualTransaction(\n        JsonNode connection,\n        String sql,\n        String database,\n        String schema,","sourceCodeStart":1026,"sourceCodeEnd":1062,"githubUrl":"https://github.com/t8y2/dbx/blob/c0390bff16418b651f4728520d99adf8ce48829a/plugins/jdbc/src/main/java/app/dbx/jdbc/DbxJdbcPlugin.java#L1026-L1062","documentation":"beginManualTransaction enforces a single active manual transaction via the static manualTransactionActive flag. If begin is called while a previous manual transaction was begun but not committed/rolled back, it throws this SQLException instead of nesting or silently reusing the existing transaction.","triggerScenarios":"Calling the begin-transaction operation twice without an intervening commit or rollback on the same plugin instance — e.g. an earlier script path errored between begin and commit, or concurrent requests both hit beginManualTransaction.","commonSituations":"Exception in the middle of a manual transaction leaving the flag set, forgetting to call commit/rollback in an error handler, or two threads/tasks sharing the plugin's static state and racing on begin.","solutions":["Commit or roll back the active manual transaction before starting a new one.","Wrap transactional work in try/finally so commit/rollback always runs, resetting the flag even on failure.","Check for an earlier operation that failed mid-transaction and left manualTransactionActive true; restart the session/plugin if stuck.","Serialize transaction usage — the plugin's transaction state is process-wide static, so avoid concurrent manual transactions."],"exampleFix":"// before\nbeginTx(conn);\nrunStatements();        // throws, no rollback\nbeginTx(conn);          // -> \"A manual transaction is already active\"\n// after\nbeginTx(conn);\ntry {\n    runStatements();\n    commitTx(conn);\n} catch (Exception e) {\n    rollbackTx(conn);\n    throw e;\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n    plugin.beginManualTransaction(connCfg);\n    // ... statements ...\n    plugin.commit();\n} catch (java.sql.SQLException e) {\n    if (e.getMessage().contains(\"already active\")) {\n        plugin.rollback();               // clear the stuck transaction\n        throw new IllegalStateException(\"Previous manual transaction was not finalized\", e);\n    }\n    throw e;\n}","preventionTips":["Always pair begin with commit/rollback in try/finally","Treat any exception inside a transaction as requiring rollback before retry","Never run concurrent manual transactions — the flag is process-wide static","Restart the plugin/session if you suspect the flag is stuck after a crash"],"tags":["jdbc","transactions","state-management"],"backgroundTag":"transaction-already-active","analyzedSha":"c0390bff16418b651f4728520d99adf8ce48829a","analyzedAt":"2026-09-05T23:05:10.900Z","contentChangedAt":"2026-09-05T23:05:10.900Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}