Welcome Guest, Not a member yet? Register   Sign In
"outer" trans_start not rolling back "inner" trans_start records
#1

I apologize if this topic has been discussed before, but I have searched the forums and cannot find the answer to my question.

What is the proper way to "nest" calls to trans_start()?
I have a module that is called by "outside" modules that may or may not call trans_start(). If they do, and I include an additional call to trans_start() in my function, I find that I get unexpected results.

Code:
function testMultipleTransStarts(){
printline('testMultipleTransStarts');

//start db transaction session
$this->db->trans_start();
//add some record somewhere
$taskName = 'Add First Task';
$featureTaskId = $this->Subscription_model->taskAdd($taskName);
printline('create record record with id: ' . $featureTaskId);


//an inner transaction that we commit
$this->db->trans_start();
$taskName = 'Add Second Task';
$featureTaskId2 = $this->Subscription_model->taskAdd($taskName);
printline('create record record with id:  ' . $featureTaskId2);
//commit the inner second db record
$this->db->trans_complete();

//roll back the OUTER transaction's db record
$this->db->trans_rollback();

printline('The "inner" 2nd db record with id: ' . $featureTaskId2 . ' should be the one stored in the database');
}

This is a simplified example for demonstration. More likely is that one function might call trans_start() and a function it calls might ALSO call trans_start().

In either case, I would expect the db record for the "inner" trans_start() to be saved, but the db record for the "outer" trans_start() to NOT be saved. In fact, BOTH are saved.

When I reverse those two lines, trans_complete() and trans_rollback(), so that rollback is called first, I would expect the "inner" db record to be rolled back and the "outer" record saved. This is in fact what happens.

It would seem that no matter how many times you call trans_start(), calling trans_complete() commits all the records, but that trans_rollback does not work in a similar way. It does not roll back all records. It rolls back the inner record, but not the outer record.

I would actually expect that the "outer" rollback should roll back all db records, including ones made within "inner" db transactions. Perhaps someone can clarify how to achieve this effect.
Reply
#2

You can have more then one query within a transaction, no need to have the second one just call the query.

Remove the second transaction parts and see how it works.
What did you Try? What did you Get? What did you Expect?

Joined CodeIgniter Community 2009.  ( Skype: insitfx )
Reply
#3

Thanks. I do know that it works with multiple queries using only one trans_start(), but my problem is I have a function that creates a lot of records and it can be called by a function that function that MAY or MAY NOT have called trans_start() already. My solution was to count the trans_start() calls by using a wrapper in a common model function like this:

function transBegin(){
$this->_transBegin += 1;
if($this->_transBegin ==1) {
$this->db->trans_begin();
}
}

function transCommit(){
if($this->_transBegin == 1) {
$this->db->trans_commit();
}
$this->_transBegin -= 1;

}

function transRollback(){
if($this->_transBegin == 1) {
$this->db->trans_rollback();
}
$this->_transBegin -= 1;
}
Reply
#4

I know that you can do many queries within one trans_start() call, of course. The problem is that I have a function that can be called by other functions that MAY or MAY NOT call trans_start() first, and there is no way to check this in CodeIgniter.

I've wound up counting with a common model that has wrappers for the transaction functions in codeIgniter:


PHP Code:
function transBegin(){
     $this->_transBegin += 1;
     if($this->_transBegin ==1) {
         $this->db->trans_begin();
     }
}

function 
transCommit(){
     if($this->_transBegin == 1) {
          $this->db->trans_commit();
     }
     $this->_transBegin -= 1;
}

function 
transRollback(){
     if($this->_transBegin == 1) {
          $this->db->trans_rollback();
     }
     $this->_transBegin -= 1;

Reply




Theme © iAndrew 2016 - Forum software by © MyBB