官網關於Yii2 事務的說明文檔
http://www.yiiframework.com/doc-2.0/guide-db-active-record.html
Working with Transactions
There are two ways of using transactions while working with Active Record.
The first way is to explicitly enclose Active Record method calls in a transactional block, like shown below,
$customer = Customer::findOne(123); Customer::getDb()->transaction(function($db) use ($customer) { $customer->id = 200; $customer->save(); // ...other DB operations... }); // or alternatively $transaction = Customer::getDb()->beginTransaction(); try { $customer->id = 200; $customer->save(); // ...other DB operations... $transaction->commit(); } catch(\Exception $e) { $transaction->rollBack(); throw $e; }
The second way is to list the DB operations that require transactional support in the yii\db\ActiveRecord::transactions() method. For example,
class Customer extends ActiveRecord { public function transactions() { return [ 'admin' => self::OP_INSERT, 'api' => self::OP_INSERT | self::OP_UPDATE | self::OP_DELETE, // the above is equivalent to the following: // 'api' => self::OP_ALL, ]; } }
The yii\db\ActiveRecord::transactions() method should return an array whose keys are scenario names and values are the corresponding operations that should be enclosed within transactions. You should use the following constants to refer to different DB operations:
- OP_INSERT: insertion operation performed by insert();
- OP_UPDATE: update operation performed by update();
- OP_DELETE: deletion operation performed by delete().
Use the |
operators to concatenate the above constants to indicate multiple operations. You may also use the shortcut constant OP_ALL to refer to all three operations above.
Transactions that are created using this method will be started before calling beforeSave() and will be committed after afterSave() has run.
Yiifans的翻譯(權威指南)文檔
事務(Transaction)
你可以向下面這樣執行一個數據庫事務:
$transaction = $connection->beginTransaction(); try { $connection->createCommand($sql1)->execute(); $connection->createCommand($sql2)->execute(); // ... 執行查詢語句 ... $transaction->commit(); } catch(Exception $e) { $transaction->rollBack(); }
還可以嵌套事務:
// 外層事務 $transaction1 = $connection->beginTransaction(); try { $connection->createCommand($sql1)->execute(); // 內層事務 $transaction2 = $connection->beginTransaction(); try { $connection->createCommand($sql2)->execute(); $transaction2->commit(); } catch (Exception $e) { $transaction2->rollBack(); } $transaction1->commit(); } catch (Exception $e) { $transaction1->rollBack(); }
多個sql執行(不同的表ActiveRecord)任意一個無法成功提交都要能回滾, 但這樣執行的時候依然插入成功而沒有回滾
SysOrderFeedback正常save, SysOrderFeedbackServer中title必須為string
$transaction = Yii::$app->db->beginTransaction(); try { $sysOrderFeeback = new \common\models\SysOrderFeedback(); $sysOrderFeeback->categ = 1; $sysOrderFeeback->ltype = 1; $sysOrderFeeback->create_time = 1; $sysOrderFeeback->total = 1; $sysOrderFeeback->open_remark = 1; $sysOrderFeeback->save(); // ...other DB operations... $sysOrderFeedbackServer = new \common\models\SysOrderFeedbackServer(); $sysOrderFeedbackServer->fid = 1; $sysOrderFeedbackServer->title = 1; $sysOrderFeedbackServer->create_time = 1; $sysOrderFeedbackServer->save(); $transaction->commit(); } catch (\Exception $e) { $transaction->rollBack(); throw $e; }
打印:
print_r($sysOrderFeedbackServer->errors);
提示Array ( [title] => Array ( [0] => Title必須是一條字符串。 ) )
開啟事務,只要沒有commit()即使驗證成功的save也保存不了,如下
$transaction = Yii::$app->db->beginTransaction(); $sysOrderFeeback = new \common\models\SysOrderFeedback(); $sysOrderFeeback->categ = 1; $sysOrderFeeback->ltype = 1; $sysOrderFeeback->create_time = 1; $sysOrderFeeback->total = 1; $sysOrderFeeback->open_remark = 1; $sysOrderFeeback->save();
后來改成下下策判斷Model->errors 暫時解決問題
$transaction = Yii::$app->db->beginTransaction(); $sysOrderFeeback = new \common\models\SysOrderFeedback(); $sysOrderFeeback->categ = 1; $sysOrderFeeback->ltype = 1; $sysOrderFeeback->create_time = 1; $sysOrderFeeback->total = 1; $sysOrderFeeback->open_remark = 1; $sysOrderFeeback->save(); // ...other DB operations... $sysOrderFeedbackServer = new \common\models\SysOrderFeedbackServer(); $sysOrderFeedbackServer->fid = 1; $sysOrderFeedbackServer->title = 1; $sysOrderFeedbackServer->create_time = 1; $sysOrderFeedbackServer->save(); if (empty($sysOrderFeeback->errors) && empty($sysOrderFeedbackServer->errors)) { $transaction->commit(); echo 'True'; } else { $transaction->rollBack(); echo 'false'; }
跟蹤Debug
關於更多的Yii2事務操作(事務級別、事務備份、事務有效性、多主從數據庫事務)查看http://www.yiichina.com/doc/guide/2.0/db-dao