使用交易處理
為何要使用交易處理
當你有很多資料庫操作,彼此關聯密切,怕會產生 race condition 存取衝突,導致最後的結果是不正確的。
希望執行時可以多個 SQL 一併執行且不受其他變更影響,把多個SQL語法整合成一個pack一起處理。
注意你的資料庫引擎是否支援交易處理
像是 InnoBD 可以用 ,MyISAM 或 ISAM 則不行。
(前置)關閉自動交易
//===============================
// 設定關閉自動提交交易
$mysqli->autocommit(FALSE);
//========== 上下擇一 ============
// PHP 5.5.0 版本以後才可以使用
// $mysqli->begin_transaction(MYSQLI_TRANS_START_READ_WRITE);
// 'MYSQLI_TRANS_START_READ_ONLY' //只讀
// 'MYSQLI_TRANS_START_READ_WRITE' //讀寫
// 'MYSQLI_TRANS_START_WITH_CONSISTENT_SNAPSHOT' //快照
//使用Procedural style **務必** 把連線放進去
//mysqli_begin_transaction($mysqli, MYSQLI_TRANS_START_READ_ONLY);
//===============================
//如果還有其他不是包再一起的SQL 可以重新開啟自動提交
//$mysqli->autocommit(TRUE);
一般 SQL 語法 使用交易機制
//開新連線 $mysqli
//確認連線
$mysqli->autocommit(FALSE);
// 開始塞一堆SQL
$mysqli->query("INSERT INTO Language VALUES ('DEU', 'Bavarian', 'F', 11.2)");
$mysqli->query("INSERT INTO Language VALUES ('DEU', 'Swabian', 'F', 9.4)");
// 提出交易
if (!$mysqli->commit()) {
$mysqli->rollback(); //因為交易失敗,所以把還原變更。
exit();
}
//如果還有其他不是包再一起的SQL 可以重新開啟自動提交
//$mysqli->autocommit(TRUE);
// 關閉連線
$mysqli->close();
Mysqli_stmt
一般
//開新連線 $mysqli
//確認連線
// PHP 5.5.0 以後才可以使用
//$mysqli->begin_transaction(MYSQLI_TRANS_START_READ_WRITE);
// 設定關閉自動提交交易
$mysqli->autocommit(FALSE);
$stmt1 = $mysqli->prepare("INSERT INTO tbl1 (id, intro) VALUES (?, ?)");
$stmt2 = $mysqli->prepare("INSERT INTO tbl2 (id, name) VALUES (?, ?)");
$str1 = 'abc';
$str2 = 'efg';
$str3 = 'hij';
$str4 = 'klm';
$stmt1->bind_param('ss', $str1, $str2);
$stmt2->bind_param('ss', $str3,$str4);
if ($stmt1->execute() == false)
{
echo 'First query failed: ' . $mysqli->error;
}
$stmt1->close();
if ($stmt2->execute() == false)
{
echo 'Second query failed: ' . $mysqli->error;
}
$stmt2->close();
$mysqli->close();
LOOP
$value = 1;
// 關閉交易
$mysqli->autocommit(FALSE);
$sql = "INSERT INTO temp (`fund_id`) VALUES (?)";
$stmt = $mysqli->prepare($sql);
$stmt->bind_param('i', $value);
foreach ($pdata as $key => $value) {
$stmt->execute();
}
$mysqli->commit();
鎖表
不過好像有機會產生把 table 鎖起來的錯誤,請小心使用。
一併提交
autocommit not only turns on/off transactions, but will also 'commit' any waiting queries.
mysqli_autocommit($link, FALSE); // turn OFF auto
-some query 1;
-some query 2;
mysqli_commit($link); // process ALL queries so far
-some query 3;
-some query 4;
mysqli_autocommit($link, TRUE); // turn ON auto