phalcon/cphalcon · error · Phalcon\Mvc\Model\Transaction\Failed
Transaction aborted
Error message
Transaction aborted
What it means
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.
Source
Thrown at phalcon/Mvc/Model/Transaction.zep:211
let manager = this->manager;
if typeof manager === "object" {
manager->notifyRollback(this);
}
let connection = this->connection;
if unlikely connection->rollback() {
if !rollbackMessage {
let rollbackMessage = "Transaction aborted";
}
if typeof rollbackRecord === "object" {
let this->rollbackRecord = rollbackRecord;
}
if this->rollbackThrowException {
throw new TxFailed(rollbackMessage, this->rollbackRecord);
}
}
return true;
}
/**
* Sets if is a reused transaction or new once
*/
public function setIsNewTransaction(bool isNew) -> void
{
let this->isNewTransaction = isNew;
}
/**
* Sets flag to rollback on abort the HTTP connection
*/
public function setRollbackOnAbort(bool rollbackOnAbort) -> voidView on GitHub (pinned to b7419de9cd)
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
Example fix
// before
$tx = $txManager->get();
$tx->throwRollbackException(true);
// ...
$tx->rollback(); // throws TxFailed 'Transaction aborted' - uncaught
// after
try {
$tx = $txManager->get();
// ... model writes ...
$tx->commit();
} catch (\Phalcon\Mvc\Model\Transaction\Failed $e) {
$record = $e->getRecord(); // model that failed, if any
$errors = $e->getMessages();
// handle abort, then discard $tx (already rolled back)
} Defensive patterns
Strategy: try-catch
Validate before calling
// If using boolean-style control, do not enable exception mode: $tx->throwRollbackException(false); // then rollback() returns true/false instead of throwing
Try / catch
try {
$tx = $txManager->get();
// ... writes ...
$tx->commit();
} catch (\Phalcon\Mvc\Model\Transaction\Failed $e) {
$failedRecord = $e->getRecord(); // model that aborted, or null
$messages = $e->getMessages(); // validation messages if any
// transaction is already rolled back at this point - do not call rollback() again
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- A dependency injection container is required to access the s
- Class '{className}' is not an ADR Action.
- Driver not supported [{driver}]
- Class '{className}' does not have a method '{name}'
- Cannot disconnect a Decorated connection instance
AI-assisted analysis of phalcon/cphalcon@b7419de9cd (2026-08-21).
Data as JSON: /api/errors/ce83facb6945737d.
Report an issue: GitHub.