We have moved our forum to GitHub Discussions. For questions about Phalcon v3/v4/v5 you can visit here and for Phalcon v6 here.

Do Rollback in onValidationFails

Can I do transaction rollback in onValidationFails?

I try

public function onValidationFails(){
      $di = $this->getDI();
      $manager = $di->get('transactionManager');
      $manager->rollbackPendent();
      $manager->collectTransactions();
      throw new \Helpers\Exception(EXCEPTION_DB_ERROR,"Error in ".get_class($this).": ".implode(" - ",parent::getMessages()));
    }

but the transaction don't finish and my phpunit test is blocked...

If I don't use onValidationFails in the model, the transaction finish.



51.1k

According to the official documentation. The operation is already stopped. "Is executed before the validation process only when an insertion operation is being made" https://docs.phalcon.io/en/latest/reference/odm.html#validation-events-and-events-manager



2.9k

Yes, the operation is already stopped. "Is executed after an integrity validator fails" https://docs.phalcon.io/en/latest/reference/models.html#events-and-events-manager, but the transactions don't finish. I don't understand because the transaction don't finish.

My code is:

class Table1 extends \Phalcon\Mvc\Model
{
    public function initialize()
    {
        $this->setSchema("public");
        $this->setSource('Table1');

        $this->hasOne('id',"Module\\Models\\Table2",'id', array(
            'foreignKey' => array(
                'action' => Relation::ACTION_CASCADE
            ),
            'alias' => 'session'
        ));
    }
}

class Table2 extends Table1
{
    public function initialize()
    {
        $this->setSchema("public");
        $this->setSource('Table2');

        $this->hasOne('id',"Module\\Models\\Table1",'id', array(
            'foreignKey' => array(
                'action' => Relation::ACTION_CASCADE
            ),
            'alias' => 'session'
        ));
    }
}

In Table2:

public function save($data=null, $whiteList=null){

    if(is_array($data) && !empty($data)){

        $this->assign($data);

        //Create a transaction manager
        $di = $this->getDI();
        $manager = $di->get('transactionManager');

        // Request a transaction
        $transaction = $manager->getOrCreateTransaction();

        try{
            $table1 = new Table1();
            $table1->setTransaction($transaction);
            if ($table1->save($data) == false) {
                $transaction->rollback(EXCEPTION_DB_ERROR . " " . implode(",",$table1->getMessages()));
            }

            $this->setTransaction($transaction);

            $this->table1 = $table1;
            $this->id = $table1->getId();

            if (parent::save($data) == false) {
                $transaction->rollback(EXCEPTION_DB_ERROR . ": " . implode(",",parent::getMessages()));
            }

            $metaData = $session->getModelsMetaData();
            $attributes = $metaData->getAttributes($session);

            //Force attributes from parent into child
            foreach($attributes as $attr){
                $this->$attr = $table1->$attr;
            }

            $transaction->commit();

        }catch(Exception $e) {
            throw new \Helpers\Exception(EXCEPTION_DB_ERROR, $e->getMessage());
        }

    }elseif($this->id) {
        $this->edit();
    }
}