首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 綜合知識

PHP mysqli 事務控制實戰:銀行轉賬功能完整實現指南

     編輯:PHP 綜合知識

什麼是資料庫事務?

在資料庫操作中,事務 是一組不可分割的 SQL 語句序列。事務遵循 ACID 原則(原子性、一致性、隔離性、持久性),確保所有操作要麼全部成功提交,要麼全部失敗回滾。這對於銀行轉賬、訂單處理等涉及多步操作的業務場景至關重要。

銀行轉賬的業務邏輯

假設用戶 A 轉帳 100 元給用戶 B,涉及兩個關鍵步驟:

  1. 從用戶 A 的賬戶扣除 100 元
  2. 向用戶 B 的賬戶增加 100 元

若第一步成功但第二步失敗(如網路中斷、資料庫錯誤),資料將處於不一致狀態——A 的錢少了,B 卻沒收到。事務控制正是為了解決此問題。

PHP mysqli 事務控制核心方法

  • autocommit(false):關閉自動提交,開啟事務模式
  • commit():提交事務,永久保存變更
  • rollback():回滾事務,撤銷所有未提交的變更

完整代碼實現

<?php
// 1. 建立資料庫連線
$mysqli = new MySQLi("localhost", "root", "123456", "liuyan");
if ($mysqli->connect_error) {
    die("連線失敗: " . $mysqli->connect_error);
}
$mysqli->query("SET NAMES 'utf8'"); // 建議使用 utf8

// 2. 關閉自動提交,啟動事務
$mysqli->autocommit(false);

// 3. 定義轉賬 SQL
$sql1 = "UPDATE account SET balance = balance - 100 WHERE id = 1;";
$sql2 = "UPDATE account SET balance = balance + 100 WHERE id = 2;";

// 4. 執行 SQL
$res1 = $mysqli->query($sql1);
$res2 = $mysqli->query($sql2);

// 5. 根據執行結果決定提交或回滾
if ($res1 && $res2) {
    $mysqli->commit();
    echo "轉賬成功!";
} else {
    $mysqli->rollback();
    echo "轉賬失敗:" . $mysqli->error;
}

// 6. 關閉連線
$mysqli->close();
?>

關鍵點解析

1. 為什麼要關閉 autocommit?

預設情況下,mysqli 每執行一條 SQL 就會自動提交。關閉後,所有查詢都在同一事務中,直到显式調用 commit() 或 rollback()。

2. 錯誤處理最佳實踐

生產環境建議使用 try-catch 捕獲異常,並記錄錯誤日誌:

try {
    $mysqli->autocommit(false);
    $mysqli->query($sql1);
    $mysqli->query($sql2);
    $mysqli->commit();
} catch (Exception $e) {
    $mysqli->rollback();
    error_log("轉賬異常: " . $e->getMessage());
}

3. 事務的隔離級別

MySQL 預設隔離級別為 REPEATABLE READ,可防止髒讀、不可重複讀、幻讀。高併發場景下可根據業務需求調整。

常見錯誤與避坑指南

  • 忘記關閉 autocommit:導致第一條 SQL 立即生效,無法回滾
  • 未判斷執行結果直接 commit:可能提交失敗的操作
  • 事務過長:長事務會鎖定資源,影響併發性能,盡量精簡事務範圍
  • 異常情況下未 rollback:如 PHP 致命錯誤、腳本超時,需註冊 shutdown function 兜底回滾

進階應用:儲存過程中的事務控制

複雜業務邏輯可封裝在 MySQL 儲存過程中,由資料庫層面保證原子性,減少網路往返:

DELIMITER //
CREATE PROCEDURE transfer(IN from_id INT, IN to_id INT, IN amount DECIMAL(10,2))
BEGIN
    DECLARE EXIT HANDLER FOR SQLEXCEPTION ROLLBACK;
    START TRANSACTION;
    UPDATE account SET balance = balance - amount WHERE id = from_id;
    UPDATE account SET balance = balance + amount WHERE id = to_id;
    COMMIT;
END//
DELIMITER ;

PHP 僅需調用 CALL transfer(1, 2, 100) 即可。

總結

掌握 mysqli 事務控制是 PHP 開發者處理金融、訂單等核心業務的必備技能。通過 autocommit(false)、commit()、rollback() 三大核心方法,配合嚴謹的錯誤處理,即可構建可靠的資料一致性保障機制。實際專案中,建議結合儲存過程、連線池、監控告警進一步提升系統穩定性。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved