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) -> void

View on GitHub (pinned to b7419de9cd)

Solutions

  1. Wrap the whole transactional unit in try/catch for \Phalcon\Mvc\Model\Transaction\Failed and treat it as the normal abort path
  2. Do not enable throwRollbackException(true) if your code checks rollback()'s boolean return - pick one style
  3. Call rollback() in exactly one place (typically the catch block); never rely on it returning quietly in exception mode
  4. 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

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


AI-assisted analysis of phalcon/cphalcon@b7419de9cd (2026-08-21). Data as JSON: /api/errors/ce83facb6945737d. Report an issue: GitHub.