事務處理支持很長時間以來一直是大多數MySQL開發者的心願
概要
如果你還不知道
對於這一點
大多數數據庫(包括MySQL)通過一個命令的組合來完成這個
* START TRANSACTION命令標志著一個新的事務組的開始
* COMMIT命令標志著一個事務組的結束
* ROLLBACK命令標志著一個事務組的結束
PHP中的事務處理函數
PHP中的MySQLi插件引進了新的函數
列表A
// connect to database
$dbh = mysqli_connect($host, $user, $pass, $db);
// turn off auto-commit
mysqli_autocommit($dbh, FALSE);
// run query 1
$result = mysqli_query($dbh, $query1);
if ($result !== TRUE) {
mysqli_rollback($dbh); // if error, roll back transaction
}
// run query 2
$result = mysqli_query($dbh, $query2);
if ($result !== TRUE) {
mysqli_rollback($dbh); // if error, roll back transaction
}
// and so on...
// assuming no errors, commit transaction
mysqli_commit($dbh);
// close connection
mysqli_close($dbh);
?>
在PHP 中執行一項事務有三個基本的步驟:
* 第一步是始終關掉數據庫的“auto-commit”,它實質上意味著系統在你作出改變時就保存它們。Tw.wINgWiT.coM這一點是很重要的,因為在一個事務處理環境中,你應該只有在確定了所有事務處理的“unit”都成功完成了以後,才保存你所做的改變。你可以通過mysqli_autocommit()函數關掉數據庫的自動提交。
* 接下來,通過mysqli_query()函數,繼續用通常的方法進行INSERT、UPDATE和/或DELETE查詢。檢驗每一個查詢返回的值,弄清楚它是否成功了是很重要的。如果其中任何一個查詢失敗了,mysqli_rollback()函數就會被用來將系統返回到事務進行之前的狀態。
* 假設組成事務組的所有命令都成功執行了,就要用mysqli_commit()函數將變化保存到數據庫系統。請注意,一旦這個函數被調用,事務就不能被撤消了。
工作實例
要了解這個在實踐中是怎麼工作的,讓我們回到前面討論過的銀行轉帳的例子.我們假設你的任務是建立一個簡單的Web應用程序,讓用戶在他們的銀行帳戶間轉帳。我們再進一步假設一個單獨用戶的帳戶存儲在一個MySQL數據庫中,如下所示:
mysql> SELECT * FROM accounts;
+----+------------+---------+
| id | label | balance |
+----+------------+---------+
| 1 | Savings #1 | 1000 |
| 2 | Current #1 | 2000 |
| 3 | Current #2 | 3000 |
+----+------------+---------+
3 rows in set (0.34 sec)
現在,需要建立一個簡單的界面,使用戶能夠輸入一個現金數額,實現從一個帳戶到另一個的轉帳。實際的“交易”將用兩個UPDATE語句來執行,一個將轉帳金額從源帳戶取出,即借方,另一個將轉帳金額記入目標帳戶,即貸方。假設我們所做的是在帳戶之間進行轉帳,那麼所有帳戶的可用結余總額($6000)應該一直保持不變。
列表B顯示了可能的代碼:
列表 B
// connect to database
$dbh = mysqli_connect("localhost", "user", "pass", "test") or die("Cannot connect");
// turn off auto-commit
mysqli_autocommit($dbh, FALSE);
// look for a transfer
if ($_POST['submit'] && is_numeric($_POST['amt'])) {
// add $$ to target account
$result = mysqli_query($dbh, "UPDATE accounts SET balance = balance + " . $_POST['amt'] . " WHERE id = " . $_POST['to']);
if ($result !== TRUE) {
mysqli_rollback($dbh); // if error, roll back transaction
}
// subtract $$ from source account
$result = mysqli_query($dbh, "UPDATE accounts SET balance = balance - " . $_POST['amt'] . " WHERE id = " . $_POST['from']);
if ($result !== TRUE) {
mysqli_rollback($dbh); // if error, roll back transaction
}
// assuming no errors, commit transaction
mysqli_commit($dbh);
}
// get account balances
// save in array, use to generate form
$result = mysqli_query($dbh, "SELECT * FROM accounts");
while ($row = mysqli_fetch_assoc($result)) {
$accounts[] = $row;
}
// close connection
mysqli_close($dbh);
?>
TRANSFER