如何在controller:cakephp中放置begincommit事务?
我正在开发一个控制器,它将更新一些表。我可以从我的控制器调用我的模型,在模型函数中,我可以开始并提交我的查询,如果发生错误,它可以回滚 这是我的样本: 控制器:如何在controller:cakephp中放置begincommit事务?,php,mysql,cakephp,Php,Mysql,Cakephp,我正在开发一个控制器,它将更新一些表。我可以从我的控制器调用我的模型,在模型函数中,我可以开始并提交我的查询,如果发生错误,它可以回滚 这是我的样本: 控制器: //update table when update button is clicked if (!empty($this->data)) { if ($this->Item->update($this->data)) { $this->Item->cr
//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
那么,是否可以在控制器中执行提交?我只能在模型中做这件事。提前谢谢 将在CakePHP的未来版本中增强传输,如中所示 这里提出了两种可能的解决方案,我将向大家展示第三种。您可以创建一个自定义方法来保存它,并手动提交事务:
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;
}
我写这段代码是为了说明我是如何思考您的问题的,尽管我没有进行测试
更有用的链接:
$ds->begin();
// do stuff and save data to models
if($success)
{
$ds->commit();
}
else
{
$ds->rollback();
}
如果我在某个步骤中退出操作并重定向或完成重定向,我实际上在不止一个地方有一个回滚或提交。这里我只举一个简单的例子
在控制器中处理事务对我来说最有意义,因为控制器操作是事务边界在概念上真正存在的地方。事务的概念自然涵盖了对多个模型的更新。我一直在使用postgres作为后端数据库,使用Cake 2.2和2.3,它在这里工作得很好。尽管我怀疑YMMV与其他db引擎有关联。我在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();
}
那么,
$this->Model->commit()
不起作用了吗?谢谢,这似乎起作用了,但是如果有很多模型,那会使代码变得混乱。如果有一个提交代码可以提交所有模型,那就更好了,是吗?是答案还是注释?如果您的模型驻留在同一个数据库中,那么这两个模型的数据源将是相同的。只需要一个数据源。第二次提交或回滚不起作用,因为提交或回滚应用于数据库中所有挂起的未提交更改。
$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();
}