Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CakePHP 2.3.x database transaction

I need your help using transactions in CakePHP.

I have a Product model, with clause hasMany to Price and Property models (key product_id).

In my Product model, I add

function begin() {
    $db =& ConnectionManager::getDataSource($this->useDbConfig);
    $db->begin($this); 
} 

function commit() {
    $db =& ConnectionManager::getDataSource($this->useDbConfig);
    $db->commit($this); 
} 
function rollback() 
{
    $db =& ConnectionManager::getDataSource($this->useDbConfig);
    $db->rollback($this); 
}

And in ProductController I use save() to save my Product, and then my Price and Property. (I use only save(), not saveAll() ).

My code is:

$this->Product->begin(); 
$error = false; 
if($this->Product->save($data) 
{ 
    //my functions and calculations 
    if(!$this->Price->save($data_one) 
    { 
        $error = true; 
    }
    //calculations
    if(!$this>Property->save($my_data)
    { 
        $error = true; 
    }
} 
if($error) {
    $this->Product->rollback();
}
else
{
    $this->Product->commit(); 
}

The problem is that if I have an error inside the save Price or Property row, the Product is still added. I would have thought that when I have any errors, none of my rows would be added (i.e. a rollback would delete it).

I am using CakePHP 2.3.8

like image 595
marczak Avatar asked Aug 03 '13 11:08

marczak


1 Answers

Tables must be in InnoDb format. MyISAM format of tables doesn't support transactions.

No need to insert additional code into model.

ProductController:

$datasource = $this->Product->getDataSource();
try {
    $datasource->begin();
    if(!$this->Product->save($data)
        throw new Exception();

    if(!$this->Price->save($data_one)
        throw new Exception();

    if(!$this->Property->save($my_data)
        throw new Exception();

    $datasource->commit();
} catch(Exception $e) {
    $datasource->rollback();
}
like image 78
Serge Rodovnichenko Avatar answered Oct 05 '22 01:10

Serge Rodovnichenko