首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫

MySQL 事務處理與表鎖定深度解析

     編輯:MySQL 資料庫相關知識

事務兩種控制方式

方式一:顯式事務語句 (推薦)

BEGIN;          -- 或 START TRANSACTION;
-- SQL 語句...
COMMIT;         -- 提交
-- 或
ROLLBACK;       -- 回滾

僅將當前語句組作為一個事務,結束後自動恢復 autocommit=1。

方式二:修改 autocommit 會話變量

SET autocommit = 0;  -- 禁用自動提交
-- 後續所有 SQL 均在事務中
COMMIT;              -- 提交並結束事務
-- 或
ROLLBACK;            -- 回滾並結束事務
-- 注意:結束同時隱式開啟新事務

存儲引擎支援事務

  • ✅ InnoDB:行級鎖、MVCC、完整 ACID
  • ✅ BDB (BerkeleyDB):較老,已少用
  • ❌ MyISAM / MEMORY / CSV / ARCHIVE 等:不支援事務

啟用 InnoDB 事務支援 (舊版本需手動)

# my.ini 註釋掉 skip-innodb
# 重啟服務
# phpMyAdmin 執行 SHOW ENGINES 確認 InnoDB = YES
# 建表/修改表指定引擎
CREATE TABLE t (...) ENGINE = InnoDB;
ALTER TABLE old_table ENGINE = InnoDB;

PHP 事務代碼範例

mysql_query("BEGIN");
$sql1 = "INSERT INTO test VALUES('11','88')";
$sql2 = "INSERT INTO test VALUES('11','88','444')";  -- 故意錯誤
$res1 = mysql_query($sql1);
$res2 = mysql_query($sql2);

if ($res1 && $res2) {
    mysql_query("COMMIT");
} else {
    mysql_query("ROLLBACK");
}

MyISAM 替代方案:表鎖定 (LOCK TABLES)

$sql_lock = "LOCK TABLES test WRITE";
mysql_query($sql_lock);

$sql_ins = "INSERT INTO test VALUES('$a','$b')";
if (mysql_query($sql_ins)) {
    echo 'successful!';
} else {
    echo 'Unsuccessful!';
}

$sql_unlock = "UNLOCK TABLES";
mysql_query($sql_unlock);

LOCK TABLES 關鍵限制

  • 同一會話內不能訪問未鎖定的表
  • 同一表在同一語句中不能出現多次(需別名)
  • 隱式提交當前事務(事務與表鎖互斥)
  • 僅支援表級鎖,併發性能遠弱於 InnoDB 行鎖

總結建議

  1. 核心業務必須使用 InnoDB + 顯式事務
  2. MyISAM 表若需原子性,遷移至 InnoDB 而非用 LOCK TABLES
  3. 事務保持短小,避免長事務阻塞
  4. 異常捕獲後必須 ROLLBACK,防止髒事務殘留
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved