如何在Yii事件中使用事务

如何在Yii事件中使用事务,yii,transactions,yii-events,Yii,Transactions,Yii Events,我知道,或者在调用$model->save()之前启动事务,并在出现异常时回滚 但是,如果我可以访问的代码的唯一位置(不管为什么)是,如何使用事务呢 若我在那个里启动事务,捕获可能的异常并回滚整个事务,那个么只会回滚删除关系模型(这里是菜单项)。它不会阻止(回滚)主记录的删除 在异常情况下,通过在我自己的beforeDelete中返回FALSE来防止删除主记录,这是否就是我需要注意的全部问题?还是应该在Yii事件中完全避免事务处理?覆盖保存方法如何: public function save($

我知道,或者在调用
$model->save()
之前启动事务,并在出现异常时回滚

但是,如果我可以访问的代码的唯一位置(不管为什么)是,如何使用事务呢

若我在那个里启动事务,捕获可能的异常并回滚整个事务,那个么只会回滚删除关系模型(这里是菜单项)。它不会阻止(回滚)主记录的删除


在异常情况下,通过在我自己的
beforeDelete
中返回
FALSE
来防止删除主记录,这是否就是我需要注意的全部问题?还是应该在Yii事件中完全避免事务处理?

覆盖保存方法如何:

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;
}

覆盖保存方法如何:

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;
}

用示例代码回答我自己的问题,进一步扩展我对Alex答案的评论:

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;
    }
}

这两个答案似乎都是正确的,两者都是相互替代的。尽管如此,我还是接受Alex的回答。用示例代码回答我自己的问题,进一步扩展我对Alex回答的评论:

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;
    }
}

这两个答案似乎都是正确的,两者都是相互替代的。尽管如此,我还是接受亚历克斯的回答,因为这会更好。

我接受你的回答作为替代。我自己的代码,在删除之前仍然使用
,与您的代码非常相似。我自己的问题的答案是(IMHO)“是”——在我自己的
beforeDelete
中返回
FALSE
,以防止主记录被删除。在这种情况下,如果出现异常(回滚事务后),我似乎需要小心。我接受您的回答作为替代。我自己的代码,在删除之前仍然使用
,与您的代码非常相似。我自己的问题的答案是(IMHO)“是”——在我自己的
beforeDelete
中返回
FALSE
,以防止主记录被删除。如果出现异常(回滚事务后),我在这种情况下需要小心。