使用交易處理

為何要使用交易處理

當你有很多資料庫操作,彼此關聯密切,怕會產生 race condition 存取衝突,導致最後的結果是不正確的。

希望執行時可以多個 SQL 一併執行且不受其他變更影響,把多個SQL語法整合成一個pack一起處理。

注意你的資料庫引擎是否支援交易處理

像是 InnoBD 可以用 ,MyISAM 或 ISAM 則不行。

參考資料 PHP官方文件

(前置)關閉自動交易

//===============================
// 設定關閉自動提交交易
$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

results matching ""

    No results matching ""