How to use transactions in Yii event

2019-08-13 13:06发布

问题:

I know, how to use transactions in pure DAO or in ActiveModel, where transaction is initiated before call to $model->save() and rolled back upon any exception.

But how to use transactions, if the only place of code I have access to (no matter, why) is Yii event?

public function beforeDelete()
{
    foreach($this->menuItems as $menuItem) $menuItem->delete();

    return parent::beforeDelete();
}

If I initiate transaction there, capture possible exception and rollback entire transaction upon it, then only deletion of relational models (here: menu items) will be rolled back. It will not prevent (roll back) deletion of master record.

Does preventing deletion of master record, by returning FALSE in my own beforeDelete in case of exception, is all I need to take care here? Or should I avoid transactions at all in Yii events?

回答1:

What about override save method:

public function save($runValidation=true,$attributes=null)
{
    $transaction=$this->getDbConnection()->beginTransaction();
    try
    {
        $result = parent::save($runValidation,$attributes);
        if($result)
            $transaction->commit();
        else
            $transaction->rollback();
    }
    catch(Exception $e)
    {
        $transaction->rollback();
        $result = false;
    }
    return $result;
}


回答2:

Answering my own question with example piece of code to further extend my comment given to Alex's answer:

public function beforeDelete()
{
    $transaction = $this->getDbConnection()->beginTransaction();

    try
    {
        foreach($this->menuItems as $menuItem) $menuItem->delete();

        $transaction->commit();
        return parent::beforeDelete();
    }
    catch(Exception $ex)
    {
        $transaction->rollback();
        return FALSE;
    }
}

Both answers seems correct, both are alternative to each other. Though, I accept Alex answer, as better.