在很多場(chǎng)景下,我們需要對(duì)多個(gè)數(shù)據(jù)庫(kù)操作進(jìn)行一起的處理。在這種情況下,PHP 提供了事務(wù)處理功能。
舉個(gè)例子,比如我們要給某個(gè)用戶賬戶里加上 100 元,同時(shí)還需要在用戶賬戶變動(dòng)記錄里增加一條記錄。這兩個(gè)操作需要作為一個(gè)原子性操作進(jìn)行,這時(shí)候我們就需要事務(wù)處理。
// 開(kāi)啟事務(wù)
mysqli_begin_transaction($conn);
// 事務(wù)處理
$result1 = mysqli_query($conn, "UPDATE account SET balance = balance + 100 WHERE user_id = 1");
$result2 = mysqli_query($conn, "INSERT INTO account_log(user_id, type, change_amount) VALUES (1, 'deposit', 100)");
// 判斷兩個(gè)操作是否都成功
if ($result1 && $result2) {
mysqli_commit($conn); // 提交事務(wù)
} else {
mysqli_rollback($conn); // 回滾事務(wù)
}
在上面的代碼中,我們使用了 mysqli_begin_transaction() 開(kāi)啟了一個(gè)事務(wù),然后在 mysqli_query() 函數(shù)中執(zhí)行了兩個(gè) SQL 語(yǔ)句。最后,根據(jù)兩個(gè)操作結(jié)果判斷事務(wù)提交或者回滾。
使用了事務(wù)處理,我們保證了操作的原子性。這意味著,要么兩個(gè)操作都成功,要么都失敗,不會(huì)出現(xiàn)其中有一個(gè)成功而另一個(gè)失敗的情況。
另外,我們還需要注意的是,在事務(wù)處理期間,我們需要使用 mysqli_commit() 函數(shù)來(lái)提交事務(wù),否則事務(wù)不會(huì)生效。如果事務(wù)內(nèi)的某個(gè)操作失敗,我們使用 mysqli_rollback() 函數(shù)進(jìn)行回滾操作。
需要注意的一點(diǎn)是,事務(wù)處理只能應(yīng)用于支持事務(wù)的存儲(chǔ)引擎,如 InnoDB。如果你的表使用的是不支持事務(wù)的存儲(chǔ)引擎,那么事務(wù)處理會(huì)被忽略。
最后,我們需要注意的是,事務(wù)處理雖然可以確保操作的原子性,但是并不是所有場(chǎng)景都使用它是合適的。對(duì)于一些不需要事務(wù)處理的簡(jiǎn)單 CRUD 操作,使用事務(wù)處理反而會(huì)增加代碼復(fù)雜度和執(zhí)行時(shí)間,影響性能。因此,在使用事務(wù)處理的時(shí)候,需要根據(jù)具體情況進(jìn)行評(píng)估和選擇。