資料庫如同感情關係:承諾永久,卻可能中途崩潰。事務技術確保「要麼全做,要麼全不做」,在多表更新、訂單生成、扣款轉賬等關鍵業務中不可或缺。MySQL 早期版本(3.22)不支援事務,開發者需自行模擬;現代版本(5.6+)InnoDB 已完美支援 ACID。
-- 業務流程:
-- 1. 生成訂單主表
-- 2. 寫入訂單明細(多筆)
-- 3. 清空購物車
-- 若第 2 步失敗,訂單主表不應存在;若第 3 步失敗,購物車殘留導致重複下單。
<?php
$pdo = new PDO('mysql:host=localhost;dbname=shop;charset=utf8mb4', 'user', 'pass', [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
]);
try {
$pdo->beginTransaction(); // 開啟事務
// 1. 插入訂單主表
$stmt = $pdo->prepare('INSERT INTO orders (user_id, total, created_at) VALUES (?, ?, NOW())');
$stmt->execute([$uid, $total]);
$orderId = $pdo->lastInsertId();
// 2. 批量插入明細
$stmt = $pdo->prepare('INSERT INTO order_items (order_id, product_id, qty, price) VALUES (?, ?, ?, ?)');
foreach ($cartItems as $item) {
$stmt->execute([$orderId, $item['pid'], $item['qty'], $item['price']]);
}
// 3. 清空購物車
$pdo->exec("DELETE FROM cart WHERE user_id = $uid");
$pdo->commit(); // 全部成功,提交
echo '下單成功,訂單號: ' . $orderId;
} catch (Exception $e) {
$pdo->rollBack(); // 任一失敗,回滾
echo '下單失敗: ' . $e->getMessage();
}
?>
status 欄位(0=處理中, 1=完成, 2=失敗),定時掃描處理中單據重試或回滾。LOCK TABLES orders WRITE, items WRITE, cart WRITE ... UNLOCK TABLES(效能極差,強烈不推薦)。結論: 早期專案務必升級 InnoDB,勿再造輪子。
SHOW ENGINE INNODB STATUS 分析,統一加鎖順序、縮短事務、避免長事務。事務是資料庫可靠性的基石。現代 PHP + MySQL 開發請直接使用 PDO 事務 API(beginTransaction/commit/rollBack),配合 InnoDB 引擎、RC 隔離級別、預處理語句,即可構建健壯的業務系統。切記:事務要短、要快、要少鎖。