t8y2/dbx · error · SQLException
No manual transaction is active
Error message
No manual transaction is active
What it means
activeManualTransactionConnection validates the preconditions for any manual-transaction operation (commit, rollback, statement execution): manualTransactionActive must be true and sharedConnection must exist and be open. If any of these fails, it throws this SQLException — the caller is attempting transaction work with no live transaction.
Source
Thrown at plugins/jdbc/src/main/java/app/dbx/jdbc/DbxJdbcPlugin.java:1090
private static ObjectNode commitManualTransaction() throws SQLException {
Connection conn = activeManualTransactionConnection(null);
conn.commit();
conn.setAutoCommit(true);
manualTransactionActive = false;
return okResult();
}
private static ObjectNode rollbackManualTransaction() throws SQLException {
Connection conn = activeManualTransactionConnection(null);
conn.rollback();
conn.setAutoCommit(true);
manualTransactionActive = false;
return okResult();
}
private static Connection activeManualTransactionConnection(JsonNode connection) throws SQLException {
if (!manualTransactionActive || sharedConnection == null || sharedConnection.isClosed()) {
throw new SQLException("No manual transaction is active");
}
if (connection != null && !connectionKey(connection).equals(sharedConnectionKey)) {
throw new SQLException("The manual transaction belongs to a different JDBC connection");
}
return sharedConnection;
}
private static ObjectNode okResult() {
ObjectNode result = MAPPER.createObjectNode();
result.put("ok", true);
return result;
}
private record ExecutedStatement(ResultSet resultSet, int updateCount) {
}
private static final class QuerySession {
private final String id;View on GitHub (pinned to c0390bff16)
Solutions
- Begin a manual transaction before attempting commit/rollback; ensure the begin call succeeded.
- Detect closed connections (SQLException on isClosed/use) and restart the transaction from begin rather than committing a dead one.
- Make commit/rollback idempotent in your orchestration: track your own in-transaction flag and skip duplicate finalization.
- If the plugin process restarted mid-transaction, treat the transaction as lost and rerun the whole unit of work.
Example fix
// before
beginTx(conn);
// connection drops; process restarts
commitTx(conn); // -> "No manual transaction is active"
// after
beginTx(conn);
try {
if (hasActiveTx()) commitTx(conn);
} catch (SQLException e) {
beginTx(conn); commitTx(conn); // restart unit of work
} Defensive patterns
Strategy: try-catch
Try / catch
try {
plugin.commitManualTransaction(connCfg);
} catch (java.sql.SQLException e) {
if (e.getMessage().contains("No manual transaction is active")) {
// transaction lost (restart/close); redo the unit of work
redoUnitOfWork(connCfg);
} else {
throw e;
}
} Prevention
- Keep transactions short to avoid idle-timeout connection drops mid-transaction
- Track your own in-transaction flag so commit is only called once
- Re-begin the transaction after any reconnect instead of committing stale state
- Remember static transaction state is lost on process restart — re-run the unit of work
When it happens
Trigger: Calling commit/rollback or running a statement inside a manual transaction when begin was never called, the transaction was already committed/rolled back, the shared connection was closed (timeout, server kill, plugin restart clearing static state), or after a plugin reload resetting manualTransactionActive.
Common situations: Connection dropped by the server between begin and commit (idle timeout, network blip), the process restarted losing static state, or script logic calling commit twice.
Related errors
- Not connected
- Not connected
- Not connected
- Transactions are not supported by this JDBC driver
- A manual transaction is already active
AI-assisted analysis of t8y2/dbx@c0390bff16 (2026-09-05).
Data as JSON: /api/errors/9f53a12b05c049d4.
Report an issue: GitHub.