BEGIN; -- 或 START TRANSACTION
-- SQL 1
-- SQL 2
COMMIT; -- 全部成功才提交
-- 或
ROLLBACK; -- 任一失敗全數回滾
優點:精確控制單一業務邊界,巢狀事務不支援(會隱式提交)。
SET autocommit = 0; -- 關閉自動提交,進入事務模式
-- SQL 1
-- SQL 2
COMMIT; -- 提交並開啟新事務
SET autocommit = 1; -- 恢復自動提交
缺點:影響整個 Session 後續所有查詢,易忘記提交導致鎖持有過久。
MyISAM、MEMORY 等不支援事務。確認支援:
SHOW ENGINES; -- 看 InnoDB 是否 YES
SHOW VARIABLES LIKE 'have_innodb';
my.ini:註釋 skip-innodb。ENGINE=InnoDB,或 ALTER TABLE t ENGINE=InnoDB。<?php
$host = 'localhost'; $user = 'root'; $pwd = 'pass'; $db = 'test';
$link = mysqli_connect($host, $user, $pwd, $db) or die('Connect failed');
mysqli_begin_transaction($link); // 或 mysqli_query($link, 'START TRANSACTION');
try {
$sql1 = "INSERT INTO open_article (nOrder, sTopic, sContent) VALUES (0, 'Topic-1', '內容-1')";
if (!mysqli_query($link, $sql1)) throw new Exception(mysqli_error($link));
$sql2 = "INSERT INTO open_article (nOrder, sTopic, sContent) VALUES (0, 'Topic-2', '內容-2')";
if (!mysqli_query($link, $sql2)) throw new Exception(mysqli_error($link));
mysqli_commit($link);
echo '事務提交成功';
} catch (Exception $e) {
mysqli_rollback($link);
echo '事務回滾: ' . $e->getMessage();
}
mysqli_close($link);
?>
若第 2 條 SQL 失敗(如欄位名拼錯),nId 自增值會跳號(如從 1 跳到 3),證明第 1 條已執行但被回滾。
innodb_flush_log_at_trx_commit = 1:最安全,每次提交刷盤。innodb_lock_wait_timeout = 50:鎖等待超時秒數。REPEATABLE READ(預設),可依業務調整為 READ COMMITTED。