Transaction on multiple AR

Hi all,

I am new to Yii, Just started to use the framework a week back and have to say its really way ahead of other frameworks I have used. Hats off to all the Developers and Contributors.

I am stuck with a problem, I want to insert new records in two of my tables using Active Record and Transaction. such that either both of the tables are inserted with new record or none, while I use the transaction I am not able to do this correctly.

Here is the first way




                        $model = User::model();

                        $model->uit = $this->_generateUit($model->name, $model->email);


                        $model->created_at = date('Y-m-d H:i:s');

                        $model->updated_at = date('Y-m-d H:i:s');


                        $token = Token::model();

                        $token->token=$token->generateToken($model->name);

                        $token->uit  = $model->uit;

                        $token->created_at=date('Y-m-d H:i:s');




                        $transaction = $token->dbConnection->beginTransaction(); // Transaction begin

                        

                        try{

                            $token->save(); // saving token

                            $model->save(); // saving user

                            

                            throw new Exception($error);  //  <---- Added to check on error condition.( test only)


                            $transaction->commit();    // committing 


                            $this->redirect(array('view','id'=>$model->id));    // Redirecting on user creation

                        }

                        catch (Exception $e){

                            $transaction->rollBack();

                        }



The following code actually saves the user to the DB, this should be as no transaction is applied on $model (User AR)

The second way





                        $model = User::model();

                        $model->uit = $this->_generateUit($model->name, $model->email);


                        $model->created_at = date('Y-m-d H:i:s');

                        $model->updated_at = date('Y-m-d H:i:s');


                        $token = Token::model();

                        $token->token=$token->generateToken($model->name);

                        $token->uit  = $model->uit;

                        $token->created_at=date('Y-m-d H:i:s');




                        $tokentransaction = $token->dbConnection->beginTransaction(); // Transaction for token begin

                        $modeltransaction = $model->dbConnection->beginTransaction(); // Transaction for model begin

                        try{

                            $token->save(); // saving token

                            $model->save(); // saving user

                            

                            $modeltransaction->commit();    // committing model

                            $tokentransaction->commit();    // committing token


                            $this->redirect(array('view','id'=>$model->id));    // Redirecting on user creation

                        }

                        catch (Exception $e){

                            $modeltransaction->rollBack();

                            $modeltransaction->rollBack();

                        }




In this case it gives out an error for a transaction being already active.

I do not want to use DAO, is there some solution to this problem using AR.

Thanks

[size=2]try this : [/size]http://www.yiiframew.../ac-audit-trail

Maybe is a silly question but, what is your DB engine? if mySQL is MyISAM or InnoDB?

Thanks, I am going through it.

Its InnoDB

The second way gives you an error obviously because you are trying to start two transactions. I am concentrating on your first example of code and all seems right.

Doing Model::model()->dbConnection->beginTransaction() is the same as Yii::app()->db->beginTransaction… You just start one transaction and end with one transaction. You are doing it right, my question is if token is also saved or is just user?

If that is the case, review the engine on User table to see if it is also InnoDB. Your code is ok as far as I know.

Thanks Antonio Ramirez, and sorry for late reply

You are right. the user table is left with MyISAM Engine by error, now its working fine.

Good to know

[size="4"]This code works successfully… [/size]

[color=#000000]$transaction [/color][color=#666600]=[/color][color=#000000] [/color][color=#660066]Yii[/color][color=#666600]::[/color][color=#000000]app[/color]color=#666600->[/color][color=#000000]db[/color][color=#666600]->[/color][color=#000000]beginTransaction[/color]color=#666600;[/color][color=#000000]

    [/color][color=#000088]try[/color][color=#000000] 


    [/color][color=#666600]{[/color][color=#000000]


            &#036;model[/color][color=#666600]-&gt;[/color][color=#000000]save[/color][color=#666600]();[/color][color=#000000]


            &#036;model2[/color][color=#666600]-&gt;[/color][color=#000000]save[/color][color=#666600]();[/color][color=#000000]


            &#036;model3[/color][color=#666600]-&gt;[/color][color=#000000]save[/color][color=#666600]();[/color][color=#000000]


            &#036;transaction[/color][color=#666600]-&gt;[/color][color=#000000]commit[/color][color=#666600]();[/color][color=#000000]


            &#036;this[/color][color=#666600]-&gt;[/color][color=#000000]redirect[/color][color=#666600]([/color][color=#000000]array[/color][color=#666600]([/color][color=#008800]'view'[/color][color=#666600],[/color][color=#008800]'id'[/color][color=#666600]=&gt;[/color][color=#000000]&#036;model[/color][color=#666600]-&gt;[/color][color=#000000]id[/color][color=#666600]));[/color][color=#000000]


    [/color][color=#666600]}[/color][color=#000000]


    [/color][color=#000088]catch[/color][color=#000000] [/color][color=#666600]([/color][color=#660066]Exception[/color][color=#000000] &#036;e[/color][color=#666600])[/color][color=#000000]


    [/color][color=#666600]{[/color][color=#000000]


            &#036;transaction[/color][color=#666600]-&gt;[/color][color=#000000]rollBack[/color][color=#666600]();[/color][color=#000000]


            [/color][color=#660066]Yii[/color][color=#666600]::[/color][color=#000000]app[/color][color=#666600]()-&gt;[/color][color=#000000]user[/color][color=#666600]-&gt;[/color][color=#000000]setFlash[/color][color=#666600]([/color][color=#008800]'error'[/color][color=#666600],[/color][color=#000000] [/color][color=#008800]&quot;{&#036;e-&gt;getMessage()}&quot;[/color][color=#666600]);[/color][color=#000000]


            &#036;this[/color][color=#666600]-&gt;[/color][color=#000000]refresh[/color][color=#666600]();[/color][color=#000000]


    [/color][color=#666600]}[/color]

If $model->save() returns false, whether made ​​$transaction->commit() ?

Just Curious To Know , What does MyISAM has to do in this case :S ?

I mean it should just throw an exception on save()

thanks for the answer =) it helped a lot ^.^