{"record":{"id":"ce83facb6945737d","repo":"phalcon/cphalcon","slug":"transaction-aborted","errorCode":null,"errorMessage":"Transaction aborted","messagePattern":"Transaction aborted","errorType":"exception","errorClass":"Phalcon\\Mvc\\Model\\Transaction\\Failed","httpStatus":null,"severity":"error","filePath":"phalcon/Mvc/Model/Transaction.zep","lineNumber":211,"sourceCode":"        let manager = this->manager;\n\n        if typeof manager === \"object\" {\n            manager->notifyRollback(this);\n        }\n\n        let connection = this->connection;\n\n        if unlikely connection->rollback() {\n            if !rollbackMessage {\n                let rollbackMessage = \"Transaction aborted\";\n            }\n\n            if typeof rollbackRecord === \"object\" {\n                let this->rollbackRecord = rollbackRecord;\n            }\n\n            if this->rollbackThrowException {\n                throw new TxFailed(rollbackMessage, this->rollbackRecord);\n            }\n        }\n\n        return true;\n    }\n\n    /**\n     * Sets if is a reused transaction or new once\n     */\n    public function setIsNewTransaction(bool isNew) -> void\n    {\n        let this->isNewTransaction = isNew;\n    }\n\n    /**\n     * Sets flag to rollback on abort the HTTP connection\n     */\n    public function setRollbackOnAbort(bool rollbackOnAbort) -> void","sourceCodeStart":193,"sourceCodeEnd":229,"githubUrl":"https://github.com/phalcon/cphalcon/blob/b7419de9cd0a8a3f48441ead84c9f8415d463e25/phalcon/Mvc/Model/Transaction.zep#L193-L229","documentation":"Phalcon\\Mvc\\Model\\Transaction::rollback() performs the underlying connection rollback; when it succeeds and the transaction was put into exception mode (throwRollbackException(true) on the transaction, or a manager that does so), a TxFailed (Phalcon\\Mvc\\Model\\Transaction\\Failed) exception with the default message 'Transaction aborted' is thrown instead of a silent false return. Rollbacks triggered by failed writes inside the transaction surface the same way.","triggerScenarios":"Calling $tx->throwRollbackException(true) and later $tx->rollback(); a save()/delete() failing inside the transaction, causing the manager to roll back and rethrow; calling rollback() both in the catch block and in normal flow so the second one throws unexpectedly.","commonSituations":"Enabling rollback exceptions for stricter semantics but not adding a matching catch; refactoring from boolean-style rollback checks to exception style; rollback() inside catch blocks of transactional service methods, causing nested throws up the stack.","solutions":["Wrap the whole transactional unit in try/catch for \\Phalcon\\Mvc\\Model\\Transaction\\Failed and treat it as the normal abort path","Do not enable throwRollbackException(true) if your code checks rollback()'s boolean return - pick one style","Call rollback() in exactly one place (typically the catch block); never rely on it returning quietly in exception mode","Inspect the exception's getRecord() and getMessages() to find which model caused the abort"],"exampleFix":"// before\n$tx = $txManager->get();\n$tx->throwRollbackException(true);\n// ...\n$tx->rollback(); // throws TxFailed 'Transaction aborted' - uncaught\n\n// after\ntry {\n    $tx = $txManager->get();\n    // ... model writes ...\n    $tx->commit();\n} catch (\\Phalcon\\Mvc\\Model\\Transaction\\Failed $e) {\n    $record  = $e->getRecord();   // model that failed, if any\n    $errors  = $e->getMessages();\n    // handle abort, then discard $tx (already rolled back)\n}","handlingStrategy":"try-catch","validationCode":"// If using boolean-style control, do not enable exception mode:\n$tx->throwRollbackException(false);\n// then rollback() returns true/false instead of throwing","typeGuard":null,"tryCatchPattern":"try {\n    $tx = $txManager->get();\n    // ... writes ...\n    $tx->commit();\n} catch (\\Phalcon\\Mvc\\Model\\Transaction\\Failed $e) {\n    $failedRecord = $e->getRecord();    // model that aborted, or null\n    $messages     = $e->getMessages();  // validation messages if any\n    // transaction is already rolled back at this point - do not call rollback() again\n}","preventionTips":["Standardize one rollback style per codebase (exceptions or booleans) and lint for the other","Call rollback() from exactly one place, usually the catch block","Log getRecord()/getMessages() when catching to preserve the abort cause","In nested service calls, let TxFailed bubble to the single owner of the transaction"],"tags":["phalcon","orm","transactions","database","rollback"],"backgroundTag":"transaction-rollback-exception","analyzedSha":"b7419de9cd0a8a3f48441ead84c9f8415d463e25","analyzedAt":"2026-08-21T06:21:18.811Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}