循環中批量 INSERT,某次失敗需撤銷前面所有 INSERT。
$pdo = new PDO("mysql:host=localhost;dbname=test", "user", "pass");
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
try {
$pdo->beginTransaction(); // 開啟事務
foreach ($dataList as $item) {
$stmt = $pdo->prepare("INSERT INTO t (col) VALUES (?)");
if (!$stmt->execute([$item])) {
throw new Exception("Insert failed"); // 觸發回滾
}
// 業務邏輯判斷
if ($someCondition) {
throw new Exception("Business rule violation");
}
}
$pdo->commit(); // 全部成功提交
echo "All inserted";
} catch (Exception $e) {
$pdo->rollBack(); // 任一失敗回滾
echo "Rolled back: " . $e->getMessage();
}
PDO::ERRMODE_EXCEPTION:讓 SQL 錯誤拋出異常,自動進入 catch 塊。beginTransaction() / commit() / rollBack() 三件套。LOAD DATA INFILE 或分批提交 (每 1000 條 commit 一次),避免長事務鎖表、日志膨脹。