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

MySQL 事務處理核心原理與 PHP/Java 實戰應用模式

     編輯:MySQL 資料庫相關知識

事務是資料庫系統區別於檔案系統的核心特性,本文從 ACID 理論、MySQL 實作機制、儲存引擎限制、應用層編程模式四個維度系統闡述。

一、事務四大特性 (ACID)

特性英文核心含義
原子性Atomicity全做或全不做,無中間狀態
一致性Consistency資料從一個合法狀態轉移到另一個合法狀態
隔離性Isolation並發事務互不干擾,如串列執行
持久性Durability提交後永久生效,故障可恢復

二、MySQL 事務控制語法

方式 1:顯式事務區塊 (推薦)

BEGIN;  -- 或 START TRANSACTION;
-- SQL 1
-- SQL 2
-- SQL 3
COMMIT;   -- 全部成功
-- 或
ROLLBACK; -- 任一失敗,全部撤銷

方式 2:關閉自動提交 (需謹慎)

SET AUTOCOMMIT = 0;
-- 後續所有 SQL 同屬一事務
COMMIT;  -- 確認
-- 或
ROLLBACK; -- 回滾
SET AUTOCOMMIT = 1; -- 恢復預設

注意: AUTOCOMMIT=0 影響整個連線生命週期,易造成長事務、鎖爭用,建議僅在明確需要的程式碼區塊使用方式 1。

三、僅 InnoDB/BDB 支援事務

-- 檢查引擎支援
SHOW VARIABLES LIKE 'have_innodb';
-- 建表必須指定
CREATE TABLE t (id INT) ENGINE=InnoDB;

MyISAM、Memory、CSV 等引擎不支援事務,操作即時生效,無法回滾。

四、完整驗證範例

mysql> USE test;
mysql> CREATE TABLE dbtest (id INT) ENGINE=InnoDB;

-- 成功提交
mysql> BEGIN;
mysql> INSERT INTO dbtest VALUES (5), (6);
mysql> COMMIT;
mysql> SELECT * FROM dbtest; -- 5, 6 存在

-- 回滾驗證
mysql> BEGIN;
mysql> INSERT INTO dbtest VALUES (7);
mysql> ROLLBACK;
mysql> SELECT * FROM dbtest; -- 僅 5, 6,7 已回滾

五、PHP 應用層事務模式

模式 1:封裝函數 (PDO 推薦)

function executeTransaction(PDO $pdo, array $sqls): bool {
    $pdo->beginTransaction();
    try {
        foreach ($sqls as $sql) {
            $pdo->exec($sql);  // 或 prepare/execute
        }
        $pdo->commit();
        return true;
    } catch (Exception $e) {
        $pdo->rollBack();
        error_log("Transaction failed: " . $e->getMessage());
        return false;
    }
}

// 使用
$pdo = new PDO("mysql:host=localhost;dbname=task", "root", "");
$success = executeTransaction($pdo, [
    "INSERT INTO trans (id) VALUES (2)",
    "INSERT INTO trans (id) VALUES (4)"
]);

模式 2:舊版 mysql_* 函數 (已棄用,僅供維護參考)

$link = mysql_connect("localhost", "root", "");
mysql_select_db("task");
mysql_query("SET AUTOCOMMIT=0");
mysql_query("BEGIN");

$ok = true;
$ok &= mysql_query("INSERT INTO trans (id) VALUES ('2')");
$ok &= mysql_query("INSERT INTO trans (id) VALUES ('4')");

if ($ok) mysql_query("COMMIT"); else mysql_query("ROLLBACK");
mysql_close($link);

六、Java/JDBC 最佳實踐

Connection conn = dataSource.getConnection();
try {
    conn.setAutoCommit(false);
    
    // 業務邏輯
    try (PreparedStatement ps1 = conn.prepareStatement("INSERT INTO t1...")) { ps1.executeUpdate(); }
    try (PreparedStatement ps2 = conn.prepareStatement("UPDATE t2...")) { ps2.executeUpdate(); }
    
    conn.commit();
} catch (SQLException e) {
    conn.rollback();
    throw new BusinessException("事務失敗", e);
} finally {
    conn.setAutoCommit(true); // 歸還連線池前恢復
    conn.close();
}

七、常見反模式與優化

  1. 長事務:事務中包含 RPC、HTTP 呼叫、大量計算 → 拆分為本地事務 + 異步補償 (Saga 模式)
  2. 大事務:一次修改百萬行 → 分批次提交、使用 pt-online-schema-change 類工具
  3. 死鎖:多表更新順序不一致 → 規範統一訪問順序、捕獲 ER_LOCK_DEADLOCK 重試
  4. 隔離級別過高:預設 REPEATABLE READ 可能產生間隙鎖 → 評估 READ COMMITTED + binlog_row_image=FULL
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved