Use of transactions in "PHP" Yii2 and Code instances

Source: Internet
Author: User
Tags yii

Use of transactions in YII2 and preamble to code examples

In general, we do business logic, and will not just associate a data table, so you will face a transaction problem.

A database transaction is a sequence of operations performed as a single logical unit of work, either completely or completely Transaction. Transaction processing ensures that data-oriented resources are not permanently updated unless all operations within the transactional unit are completed successfully. By combining a set of related actions into a single unit that either succeeds or all fails, you can simplify error recovery and make your application more reliable. To become a transaction, a logical unit of work must satisfy the so-called acid (atomicity, consistency, isolation, and persistence) attributes. A transaction is a logical unit of work in a database run, which is handled by the transaction management subsystem in the DBMS.

Get ready
    • The database engine is InnoDB
    • This article uses the Yii version of 2.0.5, as long as it is more than 2.0 there is no problem
    • Operating environment is php7.0.0,mysql5.6
Transaction handling Exceptions in Yii
    /** * Test transaction * *     Public  function actiontest(){        //Create transaction        $tr= Yii::$app->db->begintransaction ();Try{ for($i=1;$i<=3;$i++){$test=NewAreas ();$test->name =' name '.$i;$test->sort=1;if($test->save ()) {Echo "Save $i |"; }            }$test=NewAreas ();$test->name =' AB '.$i;$test->sorta=1;//write to a field that does not exist            if(!$test->save ()) {"Save Fail";//If the output is not written}//Submit            $tr->commit (); }Catch(Exception $e) {//Roll back            $tr->rollback ();Echo  "Rollback"; }    }

Run results

1| save 2 | save 3 | rollback

Note that because the last data is not successfully inserted, the rollback of the transaction is triggered, so the data table has no new data to produce.

The reason for triggering a transaction rollback is that the code has an exception (Exception).

Failed to process data

In general, there is no such obvious anomaly in our running code, which is eliminated during the development test.

What really caused the data to roll back was a problem with one of our businesses, which resulted in no part of the data being written.

    /** * Test transaction * *     Public  function actiontest(){        //Create transaction        $tr= Yii::$app->db->begintransaction ();Try{ for($i=1;$i<=3;$i++){$test=NewAreas ();$test->name =' name '.$i;$test->sort=1;if($test->save ()) {Echo "Save $i |"; }            }$test=NewAreas ();$test->name =NULL;//Database design name cannot be null, man-made write failed.             $test->sort=1;//write to a field that does not exist            if(!$test->save ()) {Echo  "Save Fail";//If the output is not written}//Submit            $tr->commit (); }Catch(Exception $e) {//Roll back            $tr->rollback ();Echo  "Rollback"; }    }

The results of the operation are as follows, with three data inserted into the database.

123fail

That is, if a data table is not written to data because of business logic, there is no corresponding rollback.

The improvement scheme is as follows

    /** * Test transaction * *     Public  function actiontest(){        //Create transaction        $tr= Yii::$app->db->begintransaction ();Try{ for($i=1;$i<=3;$i++){$test=NewAreas ();$test->name =' name '.$i;$test->sort=1;if($test->save ()) {Echo "Save $i |"; }            }$test=NewAreas ();$test->name =NULL;//Database design name cannot be null, man-made write failed.             $test->sort=1;//write to a field that does not exist            if(!$test->save ()) {Throw New\yii\db\Exception();//Manually throw an exception, which is captured by the following. }//Submit            $tr->commit (); }Catch(Exception $e) {//Roll back            $tr->rollback ();Echo  "Rollback"; }    }

The results are as follows: The database is not inserting new data and the transaction is rolled back.

1| save 2 | save 3 | rollback
Decentralized data processing

Due to the complexity of the actual project, our database operations are scattered in different model.

Therefore, the actual project code will not be the above look.

Simulation requirements

Receive parameters:

  • Name
  • Gender
  • Signature

Business Process Flow:

  1. Receive parameters
  2. The UID of the user is obtained by the generator, and a digit is added to the corresponding data table of the generator number.
  3. Write the name, gender, signature, and UID of the previous step to the User information table
  4. Initialize User Balance Table

Rollback Trigger Time:

  • Initialize Balance table no incoming UID export no write data

Actual code

//controller    /** * Test Transaction-Registered user */     Public  function actionreg() {        //Get request        $request= Yii::$app->request;//Set return format        $response= Yii::$app->response;$response->format = \yii\web\response::format_json;//Return JSON        //test code, remove authentication step        $name=$request->get ("Name");$gender=$request->get ("Gender");$sign=$request->get ("Sign");//test code, omit parameter check step        $tr= Yii::$app->db->begintransaction ();Try{//Get UID            $uid= App::getseno (); Userprofile::add ($uid,$name,$gender,1,$sign);$user _balance= Userbalance::inituserbalance ($uid);$tr->commit ();//Submit data}Catch(Exception $e) {//Roll back            $tr->rollback ();return $e->getmessage ();//Return custom exception information}return $user _balance; }//userprofile    /** * Add user information * @param $user _id * @param $nikename * @param $gender *
     
       @param $user _type *
       @param string $intro *
       @return userprofile *
       @throws \ex Ception * *
          Public Static  function add($user _id, $nikename, $gender,$ User_type,$intro="") {        $model=NewUserProfile ();$model->gender =$gender;$model->nikename =$nikename;$model->user_id =$user _id;$model->user_type=$user _type;$model->intro=$intro;$model->update_time = time ();$insert=$model->insert ();if(!$insert){Throw New Exception("User profile not written"); }return $model; }//userbalance    /** * Initialize the user's cash withdrawal balance * @param $user _id */     Public Static  function inituserbalance($user _id){        $info= Self:: Find ()->where ([' user_id '=$user _id])->one ();if(!$info){$model=NewUserbalance ();$model->user_id =$user _id;$model->price="0";$model->update_time=time ();$insert=$model->insert ();if(!$insert){Throw New Exception("No user balances initialized"); }$info=$model; }return $info->attributes; }

The normal results are as follows

{"id":124,"user_id":1473179883,"price":"0","update_time":1473179883}

If the user_id of the initialized user balance portion is not successfully delivered, the results returned are as follows

"没有初始化用户余额"

We can be targeted to the specific situation where the error is located, timely modification.

Transactions (Transaction)

As can be seen from the actual code above, the transaction is created, so long as it is within the scope, even the other model introduced can return the exception ng and complete the rollback operation.

In general, the entire YII application uses the same database connection, or uses a singleton.

In the other yii\db\Connection , the transaction object is cached:

 class Connection extends Component{    //Save valid transaction object for current connection    Private $_transaction;If a transaction object is already cached, and the transaction object is valid, the transaction object is returned    //returns null otherwise     Public  function gettransaction() {        return $this->_transaction &&$this->_transaction->getisactive ()?$this->_transaction:NULL; }//See how transaction objects are used when transactions are enabled     Public  function begintransaction($isolationLevel = null) {        $this->open ();//Cached transaction object is valid, the transaction object in the cache is used        //Create a new transaction object otherwise        if(($transaction=$this->gettransaction ()) = = =NULL) {$transaction=$this->_transaction =NewTransaction ([' DB '=$this]); }$transaction->begin ($isolationLevel);return $transaction; }}

Therefore, it can be considered that the whole YII application uses the same Transaction object, that is to say, Transaction::_level has continuity throughout the life cycle of the application. This is the key and prerequisite for implementing transaction nesting.

Summarize

The level of technical growth comes from stepping on pits and stepping on pits from business growth.

Have time to talk about career planning and development. : )

Resources
    • http://www.yiichina.com/question/1576
    • Http://www.digpage.com/transaction.html
    • Http://baike.baidu.com/link?url=1-LvBZQ2hgY9-9HcjQrzf3KCsf-iGzRK3FggAYC5mldYukCQ44B2aNTds7ODDz7bLBNtYfxpjH_tpSsNeoMAsK

Use of transactions in "PHP" Yii2 and Code instances

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.