title: Phalcon: transactions and complex models
body: <p>In my project i have <code>entities</code> table, where all entities should exist (to support complex foreign keys), so i need to insert additional row in special table (in this entities list) before inserting a row to my model table, and i wanted to ask what is the best way to do this.</p>
  
  <p>So, for following code i need to insert two rows: in <code>entity</code> table, then pick up id for just inserted row, save it in current model and insert in <code>accounts</code> table:</p>
  
  <pre><code>$account = new Account();
  $account-&gt;name = 'John';
  $account-&gt;save(); // performs two inserts while creating model
  </code></pre>
  
  <p>As i understood, i can use beforeCreate() method to insert row in <code>entity</code> table and to pick up id for newly created row, smth like this:</p>
  
  <pre><code>class Account
  {
      public function beforeSave()
      {
          $entity = new \Entity();
          $entity-&gt;type = get_class($this);
          $entity-&gt;save();
          $this-&gt;id = $entity-&gt;id;
      }
  }
  </code></pre>
  
  <p>But this way, if somehow account row will be not inserted, row in <code>entity</code> table will exist. </p>
  
  <p>Then i thought to use transactions as shown in docs here <a href="http://docs.phalconphp.com/en/latest/reference/models.html#transactions" rel="nofollow">http://docs.phalconphp.com/en/latest/reference/models.html#transactions</a></p>
  
  <p>But i don't unserstand, if i have small transactions for every model::create() method, how it will work when i will need transactions for complex operations?</p>
  
  <p>e.g. </p>
  
  <pre><code>// controller action context
  use Phalcon\Mvc\Model\Transaction\Manager as TxManager,
      Phalcon\Mvc\Model\Transaction\Failed as TxFailed;
  
  try {
  
      //Create a transaction manager
      $manager = new TxManager();
  
      // Request a transaction
      $transaction = $manager-&gt;get();
  
      $account = new Account();
      $account-&gt;setTransaction($transaction);
      $account-&gt;name = "WALL·E";
      $account-&gt;created_at = date("Y-m-d");
      if ($account-&gt;save() == false) { // sub-transaction inside account::create() method
          $transaction-&gt;rollback("Cannot save account");
      }
  
      $accountPart = new AccountPart();
      $accountPart-&gt;setTransaction($transaction);
      $accountPart-&gt;type = "head";
      if ($accountPart-&gt;save() == false) { // sub-transaction inside accountPart::create() method
          $transaction-&gt;rollback("Cannot save account part");
      }
  
      //Everything goes fine, let's commit the transaction
      $transaction-&gt;commit();
  
  } catch(TxFailed $e) {
      echo "Failed, reason: ", $e-&gt;getMessage();
  }
  </code></pre>
  
  <p>It's hard to imagine how it will work in big project.. nested transactions it's not very good for database perfomance</p>
  
  <p>Also i thought about 3d method of implementation, i've added it's code below, but it looks like a hack and i also don't want to use it:</p>
  
  <pre><code>public function create($data = null)
  {   
      // Create abstract entity instance
      $entity = new \Entity();
      $entity-&gt;type = get_class($this);
  
      // Save abstract entity
      if (!$entity-&gt;save()) {
          return false;
      }
  
      // Save current entity
      $this-&gt;id = $entity-&gt;id;
      $result = parent::create($data);
  
      // Remove abstract entity if current row was not saved
      if (!$result) {
          $entity-&gt;delete();
      }
  
      return $result;
  }
  </code></pre>
  
  <p>What is the best and easy way to support such complex entities?</p>