繁体   English   中英

如何在控制器中放置begin-commit事务:cakephp?

[英]How to put begin-commit transaction in controller: cakephp?

我正在研究一个会更新几张桌子的控制器。 我可以从我的控制器调用我的模型,在模型函数内部我可以开始并提交我的查询,它可以在发生错误时回滚。

这是我的样本:

控制器:

//update table when update button is clicked
    if (!empty($this->data)) {
        if ($this->Item->update($this->data)) {
            $this->Item->create();
            $this->redirect('/sample');
            return;
        } else {
            $this->set('data', $this->data);
        }
    }

模型:

function update($data)
{
    $this->begin($this);
    if(!parent::save($data)) {
        $this->rollback($this);
        return false;
    }

    $this->commit();
    return true;
}

现在这很好用。 但我需要做的是在我的控制器中调用另一个模型,如“$ this - >”这里的另一个模型“ - > update()”。 如果模型事务发生问题,我需要回滚。 我想的是在模型调用成功后在我的控制器中提交一个提交。

很像这样:

CONTROLLER PHP:
  BEGIN TRANSACTION
    ->CALLS MODEL1
        IF(MODEL1 == ERROR){
             ROLLBACK
        }
    ->CALLS MODEL2
        IF(MODEL2 == ERROR){
             ROLLBACK
        }
   COMMIT WHEN NO PROBLEM IS ENCOUNTERED

那么可以在控制器中执行提交吗? 我只能在模型中做到这一点。 提前致谢!

那么可以在控制器中执行提交吗? 我只能在模型中做到这一点。

是的,您可以在控制器内执行提交或回滚。 您需要先从其中一个模型获取数据源。 在控制器代码中,只需引用您正在使用的模型之一(假设它们都在同一个数据库中):

$ds = $this->MyModelName->getdatasource();

然后,您可以从控制器中开始,提交和回滚到该数据源。

$ds->begin();

// do stuff and save data to models

if($success)
{
    $ds->commit();
}
else
{
    $ds->rollback();
}

我实际上有一个回滚或提交在一个以上的地方,如果我正在采取行动,并在一些步骤重定向或最终确定并重定向。 我在这里举一个简单的例子。

处理控制器中的事务对我来说是最有意义的,因为控制器操作是事务边界在概念上真正存在的位置。 交易的想法自然会跨越多个模型的更新。 我一直在使用postgres作为Cake 2.2和2.3的后端数据库,它在这里工作正常。 我怀疑YMMV与其他数据库引擎有关。

正如您在CakePHP灯塔门票中所看到的, CakePHP的期货版本将增强Trasactions。

那里提出了两种可能的解决方案,我将向您展示第三种解决方案。 您可以创建一个自定义方法来保存它,并手动提交事务:

public function saveAndUpdate($data) {
    $ds = $this->getDataSource();
    $ds->begin();
    if ($this->save($data)) {
        foreach(Array('Model1', 'Model2') as $model) {
            if (!ClassRegistry::init($model)->update()) {
                $db->rollback();
                return false;
             }
         }
         return $db->commit() !== false;
     }
     return false;
 }

我写了这段代码来说明我对你的问题的看法,尽管我没有测试过。

更有用的链接:

我在if语句中使用了commit,在我的else语句中使用了rollback。 由于我在控制器中使用了两个不同的模型,因此我创建了两个不同的数据源

        $transactiondatasource = $this->Transaction->getDataSource();
        $creditcarddatasource = $this->Creditcard->getDataSource();
        $transactiondatasource->begin();
        $creditcarddatasource->begin();

        if (CONDITION){
                $creditcarddatasource->commit();
                $transactiondatasource->commit();
                CakeSession::delete('Cart');
            } else {
                $this->Session->setFlash(__('MESSAGE'));
                $creditcarddatasource->rollback();
                $transactiondatasource->rollback();
            }   

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM