{"record":{"id":"370d5ad63471c9d4","repo":"prestodb/presto","slug":"not-in-transaction-370d5a","errorCode":"NOT_IN_TRANSACTION","errorMessage":"No transaction in progress","messagePattern":"No transaction in progress","errorType":"error_code","errorClass":"PrestoException","httpStatus":null,"severity":"error","filePath":"presto-main-base/src/main/java/com/facebook/presto/execution/RollbackTask.java","lineNumber":45,"sourceCode":"\nimport static com.facebook.presto.spi.StandardErrorCode.NOT_IN_TRANSACTION;\nimport static com.google.common.util.concurrent.Futures.immediateFuture;\n\npublic class RollbackTask\n        implements SessionTransactionControlTask<Rollback>\n{\n    @Override\n    public String getName()\n    {\n        return \"ROLLBACK\";\n    }\n\n    @Override\n    public ListenableFuture<?> execute(Rollback statement, TransactionManager transactionManager, Metadata metadata, AccessControl accessControl, QueryStateMachine stateMachine, List<Expression> parameters, String query)\n    {\n        Session session = stateMachine.getSession();\n        if (!session.getTransactionId().isPresent()) {\n            throw new PrestoException(NOT_IN_TRANSACTION, \"No transaction in progress\");\n        }\n        TransactionId transactionId = session.getTransactionId().get();\n\n        stateMachine.clearTransactionId();\n        transactionManager.asyncAbort(transactionId);\n        return immediateFuture(null);\n    }\n}\n","sourceCodeStart":27,"sourceCodeEnd":54,"githubUrl":"https://github.com/prestodb/presto/blob/55bb57d202de3b926896fa966c2c4a44c779634e/presto-main-base/src/main/java/com/facebook/presto/execution/RollbackTask.java#L27-L54","documentation":"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.","triggerScenarios":"Executing ROLLBACK when session.getTransactionId() is empty — no START TRANSACTION was issued, or the transaction already committed/aborted/timed out.","commonSituations":"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.","solutions":["Issue START TRANSACTION before ROLLBACK","Track transaction state and only send ROLLBACK when a transaction is active","Catch PrestoException with NOT_IN_TRANSACTION and treat it as a no-op if ROLLBACK is best-effort"],"exampleFix":"// before\nsession.execute(\"ROLLBACK\");\n// after\nif (session.getTransactionId().isPresent()) {\n    session.execute(\"ROLLBACK\");\n}","handlingStrategy":"try-catch","validationCode":"// Skip ROLLBACK when no transaction is active\nif (!session.getTransactionId().isPresent()) {\n    return; // nothing to roll back\n}","typeGuard":null,"tryCatchPattern":"try {\n    rollbackTask.execute(statement, transactionManager, metadata, accessControl, stateMachine, parameters, query);\n} catch (PrestoException e) {\n    if (e.getErrorCode() == StandardErrorCode.NOT_IN_TRANSACTION.toErrorCode()) {\n        // treat as no-op: transaction already ended\n    } else {\n        throw e;\n    }\n}","preventionTips":["Pair every START TRANSACTION with exactly one COMMIT or ROLLBACK","Be aware transactions can time out server-side; do not assume a prior START guarantees an active txn","Make best-effort cleanup ROLLBACKs tolerant of NOT_IN_TRANSACTION"],"tags":["sql","transactions","rollback","semantic-error"],"backgroundTag":"no-transaction-in-progress","analyzedSha":"55bb57d202de3b926896fa966c2c4a44c779634e","analyzedAt":"2026-09-04T12:50:26.162Z","contentChangedAt":"2026-09-04T12:50:26.162Z","schemaVersion":2},"datasetVersion":"2026-09-11T21:17:09.523Z"}