prestodb/presto · error · PrestoException

NOT_IN_TRANSACTION

NOT_IN_TRANSACTION

Error message

No transaction in progress

What it means

ROLLBACK aborts the current session transaction; if the session has no active transaction id, Presto throws NOT_IN_TRANSACTION. This includes the case where the transaction already ended (committed, aborted, or timed out) before the ROLLBACK ran.

Source

Thrown at presto-main-base/src/main/java/com/facebook/presto/execution/RollbackTask.java:45

import static com.facebook.presto.spi.StandardErrorCode.NOT_IN_TRANSACTION;
import static com.google.common.util.concurrent.Futures.immediateFuture;

public class RollbackTask
        implements SessionTransactionControlTask<Rollback>
{
    @Override
    public String getName()
    {
        return "ROLLBACK";
    }

    @Override
    public ListenableFuture<?> execute(Rollback statement, TransactionManager transactionManager, Metadata metadata, AccessControl accessControl, QueryStateMachine stateMachine, List<Expression> parameters, String query)
    {
        Session session = stateMachine.getSession();
        if (!session.getTransactionId().isPresent()) {
            throw new PrestoException(NOT_IN_TRANSACTION, "No transaction in progress");
        }
        TransactionId transactionId = session.getTransactionId().get();

        stateMachine.clearTransactionId();
        transactionManager.asyncAbort(transactionId);
        return immediateFuture(null);
    }
}

View on GitHub (pinned to 55bb57d202)

Solutions

  1. Issue START TRANSACTION before ROLLBACK
  2. Track transaction state and only send ROLLBACK when a transaction is active
  3. Catch PrestoException with NOT_IN_TRANSACTION and treat it as a no-op if ROLLBACK is best-effort

Example fix

// before
session.execute("ROLLBACK");
// after
if (session.getTransactionId().isPresent()) {
    session.execute("ROLLBACK");
}
Defensive patterns

Strategy: try-catch

Validate before calling

// Skip ROLLBACK when no transaction is active
if (!session.getTransactionId().isPresent()) {
    return; // nothing to roll back
}

Try / catch

try {
    rollbackTask.execute(statement, transactionManager, metadata, accessControl, stateMachine, parameters, query);
} catch (PrestoException e) {
    if (e.getErrorCode() == StandardErrorCode.NOT_IN_TRANSACTION.toErrorCode()) {
        // treat as no-op: transaction already ended
    } else {
        throw e;
    }
}

Prevention

When it happens

Trigger: Executing ROLLBACK when session.getTransactionId() is empty — no START TRANSACTION was issued, or the transaction already committed/aborted/timed out.

Common situations: Client autocommit wrappers issuing ROLLBACK without a prior START TRANSACTION; transaction expired server-side while the client still sends ROLLBACK; double ROLLBACK in error-handling paths.

Related errors


AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04). Data as JSON: /api/errors/370d5ad63471c9d4. Report an issue: GitHub.