Yii 內建支援資料庫事務,配合 ActiveRecord 或 Query Builder 即可實現 ACID 特性。本文針對批次寫入、刪除等場景,提供標準事務範本與關鍵注意事項。
Yii::app()->db->beginTransaction():開啟事務,回傳 CDbTransaction 實例。$transaction->commit():提交事務,持久化所有變更。$transaction->rollback():回滾事務,撤銷所有未提交變更。<?php
// 假設資料來源
$users = [
['username' => 'phpernote.com_0', 'password' => '123456'],
['username' => 'u_1', 'password' => '123456'],
['username' => 'u_2', 'password' => '123456'],
];
$transaction = Yii::app()->db->beginTransaction();
try {
foreach ($users as $user) {
// 使用 Command Builder 插入,參數自動綁定防注入
Yii::app()->db->createCommand()->insert('tbl_user', $user);
}
$transaction->commit();
echo "批次新增成功";
} catch (Exception $e) {
$transaction->rollback();
echo "事務回滾: " . $e->getMessage();
// 可記錄日誌: Yii::log($e->getMessage(), CLogger::LEVEL_ERROR);
}
?>
ENGINE=InnoDB。try 區塊需包含所有需原子性的操作;若在迴圈外呼叫其它方法,確保該方法拋出的異常能冒泡到此處。$transaction->setIsolationLevel(Transaction::READ_COMMITTED) 設定(需 Yii 1.1.14+),預設為資料庫預設級別 (通常 REPEATABLE READ)。Yii 2.0 內建支援 Savepoint,Yii 1.x 需手動實作:
<?php
// 在現有事務中建立儲存點
$transaction->getDbConnection()->createCommand("SAVEPOINT sp1")->execute();
// ... 執行子操作 ...
// 子操作失敗時回滾到儲存點
$transaction->getDbConnection()->createCommand("ROLLBACK TO SAVEPOINT sp1")->execute();
// 子操作成功時釋放儲存點
$transaction->getDbConnection()->createCommand("RELEASE SAVEPOINT sp1")->execute();
?>
善用事務保障資料一致性,是後端開發的基本功。