Model Transactions


    When a process performs multiple database operations, it might be important that each step is completed successfully so that data integrity can be maintained. Transactions offer the ability to ensure that all database operations have been executed successfully before the data is committed to the database.

    Transactions in Phalcon allow you to commit all operations if they were executed successfully or rollback all operations if something went wrong.

    Existing relationships can be used to store records and their related instances, this kind of operation implicitly creates a transaction to ensure that data is correctly stored:

    1. $robotPart = new RobotParts();
    2. $robotPart->type = 'head';
    3. $robot = new Robots();
    4. $robot->name = 'WALL-E';
    5. $robot->created_at = date('Y-m-d');
    6. $robot->robotPart = $robotPart;
    7. // Creates an implicit transaction to store both records
    8. $robot->save();

    Isolated transactions are executed in a new connection ensuring that all the generated SQL, virtual foreign key checks and business rules are isolated from the main connection. This kind of transaction requires a transaction manager that globally manages each transaction created ensuring that they are correctly rolled back/committed before ending the request:

    1. <?php
    2. use Phalcon\Mvc\Model\Transaction\Failed as TxFailed;
    3. use Phalcon\Mvc\Model\Transaction\Manager as TxManager;
    4. // Create a transaction manager
    5. $manager = new TxManager();
    6. $transaction = $manager->get();
    7. // Get the robots to be deleted
    8. $robots = Robots::find(
    9. "type = 'mechanical'"
    10. );
    11. foreach ($robots as $robot) {
    12. $robot->setTransaction($transaction);
    13. // Something's gone wrong, we should rollback the transaction
    14. if ($robot->delete() === false) {
    15. $messages = $robot->getMessages();
    16. foreach ($messages as $message) {
    17. $transaction->rollback(
    18. $message->getMessage()
    19. );
    20. }
    21. }
    22. }
    23. // Everything's gone fine, let's commit the transaction
    24. $transaction->commit();
    25. echo 'Robots were deleted successfully!';
    26. } catch (TxFailed $e) {
    27. echo 'Failed, reason: ', $e->getMessage();
    28. }

    Transactions are reused no matter where the transaction object is retrieved. A new transaction is generated only when a commit() or :code:rollback() is performed. You can use the service container to create the global transaction manager for the entire application:

    Then access it from a controller or view:

    1. <?php
    2. use Phalcon\Mvc\Controller;
    3. class ProductsController extends Controller
    4. {
    5. public function saveAction()
    6. {
    7. // Obtain the TransactionsManager from the services container
    8. $manager = $this->di->getTransactions();
    9. // Or
    10. $manager = $this->transactions;
    11. // Request a transaction
    12. $transaction = $manager->get();
    13. // ...
    14. }