久久福利_99r_国产日韩在线视频_直接看av的网站_中文欧美日韩_久久一

您的位置:首頁技術(shù)文章
文章詳情頁

用新PHP插件實(shí)現(xiàn)MySQL為基礎(chǔ)的事務(wù)

瀏覽:132日期:2024-02-10 17:03:54

事務(wù)處理支持很長(zhǎng)時(shí)間以來一直是大多數(shù)MySQL開發(fā)者的心愿,隨著MySQL 4.0的發(fā)布,這個(gè)心愿最后終于得以實(shí)現(xiàn)。MySQL 4.0后不久,擁有一個(gè)新的MySQL插件的PHP 5.x也發(fā)布了。這個(gè)新插件,MySQL Improved,使得PHP開發(fā)者通過利用本地的PHP函數(shù),獲得了這些新的事務(wù)處理能力。這篇簡(jiǎn)短的教程將向你說明怎樣利用這些新的MySQLi函數(shù),用PHP實(shí)現(xiàn)以MySQL為基礎(chǔ)的事務(wù)。

概要

如果你還不知道,那么我可以告訴你,事務(wù)只是一組SQL語句,通常因?yàn)樗鼈兪潜舜讼嗷ヒ蕾嚨模砸谌谢蛉珶o(all-or-nothing)的模式下執(zhí)行。只有當(dāng)所有組成的語句都執(zhí)行成功了,一個(gè)事務(wù)才算是成功了;任何一個(gè)語句中的失敗應(yīng)該都會(huì)導(dǎo)致系統(tǒng)“回滾”到它先前的狀態(tài),以避免數(shù)據(jù)連接/崩潰問題。

對(duì)于這一點(diǎn),兩個(gè)銀行帳戶間的轉(zhuǎn)帳是一個(gè)很好的例子。在數(shù)據(jù)庫(kù)級(jí),這樣的轉(zhuǎn)帳包括兩個(gè)步驟:首先,從源帳戶中扣除轉(zhuǎn)帳的金額,然后將其加到目標(biāo)帳戶中。如果在第二步中發(fā)生了錯(cuò)誤,那么第一步就必須被取消,以避免不相符的情況(和憤怒的客戶聚眾滋事)。事務(wù)安全系統(tǒng)將自動(dòng)地撤到系統(tǒng)先前的“快照”。

大多數(shù)數(shù)據(jù)庫(kù)(包括MySQL)通過一個(gè)命令的組合來完成這個(gè):

* START TRANSACTION命令標(biāo)志著一個(gè)新的事務(wù)組的開始。它后面常接一系列的SQL命令。

* COMMIT命令標(biāo)志著一個(gè)事務(wù)組的結(jié)束,表示事務(wù)期間做的所有改變應(yīng)該被提交或者使之永久化。

* ROLLBACK命令標(biāo)志著一個(gè)事務(wù)組的結(jié)束,表示事務(wù)期間所做的所有改變應(yīng)該被撤消。

PHP中的事務(wù)處理函數(shù)

PHP中的MySQLi插件引進(jìn)了新的函數(shù),幫助開發(fā)者利用MySQL的事務(wù)處理能力。實(shí)質(zhì)上,這些函數(shù)對(duì)等地被叫做SQL START TRANSACTION,COMMIT和 ROLLBACK命令。列表A為你展示了一個(gè)例子,列表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 中執(zhí)行一項(xiàng)事務(wù)有三個(gè)基本的步驟:

* 第一步是始終關(guān)掉數(shù)據(jù)庫(kù)的“auto-commit”,它實(shí)質(zhì)上意味著系統(tǒng)在你作出改變時(shí)就保存它們。這一點(diǎn)是很重要的,因?yàn)樵谝粋€(gè)事務(wù)處理環(huán)境中,你應(yīng)該只有在確定了所有事務(wù)處理的“unit”都成功完成了以后,才保存你所做的改變。你可以通過mysqli_autocommit()函數(shù)關(guān)掉數(shù)據(jù)庫(kù)的自動(dòng)提交。

* 接下來,通過mysqli_query()函數(shù),繼續(xù)用通常的方法進(jìn)行INSERT、UPDATE和/或DELETE查詢。檢驗(yàn)每一個(gè)查詢返回的值,弄清楚它是否成功了是很重要的。如果其中任何一個(gè)查詢失敗了,mysqli_rollback()函數(shù)就會(huì)被用來將系統(tǒng)返回到事務(wù)進(jìn)行之前的狀態(tài)。

* 假設(shè)組成事務(wù)組的所有命令都成功執(zhí)行了,就要用mysqli_commit()函數(shù)將變化保存到數(shù)據(jù)庫(kù)系統(tǒng)。請(qǐng)注意,一旦這個(gè)函數(shù)被調(diào)用,事務(wù)就不能被撤消了。

工作實(shí)例

要了解這個(gè)在實(shí)踐中是怎么工作的,讓我們回到前面討論過的銀行轉(zhuǎn)帳的例子.我們假設(shè)你的任務(wù)是建立一個(gè)簡(jiǎn)單的Web應(yīng)用程序,讓用戶在他們的銀行帳戶間轉(zhuǎn)帳。我們?cè)龠M(jìn)一步假設(shè)一個(gè)單獨(dú)用戶的帳戶存儲(chǔ)在一個(gè)MySQL數(shù)據(jù)庫(kù)中,如下所示:

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)

現(xiàn)在,需要建立一個(gè)簡(jiǎn)單的界面,使用戶能夠輸入一個(gè)現(xiàn)金數(shù)額,實(shí)現(xiàn)從一個(gè)帳戶到另一個(gè)的轉(zhuǎn)帳。實(shí)際的“交易”將用兩個(gè)UPDATE語句來執(zhí)行,一個(gè)將轉(zhuǎn)帳金額從源帳戶取出,即借方,另一個(gè)將轉(zhuǎn)帳金額記入目標(biāo)帳戶,即貸方。假設(shè)我們所做的是在帳戶之間進(jìn)行轉(zhuǎn)帳,那么所有帳戶的可用結(jié)余總額($6000)應(yīng)該一直保持不變。

列表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);

?>像你所看到的那樣,腳本以連接數(shù)據(jù)庫(kù)和關(guān)閉自動(dòng)提交開始。然后執(zhí)行一個(gè)SELECT查詢,檢索所有帳戶的現(xiàn)金收支,接著構(gòu)造一個(gè)有下拉式界面的表格,選擇交易要用到的來源/目標(biāo)帳戶。圖表A顯示了最初的表格。

最初的表格

一旦表格完成并提交后,兩個(gè)UPDATE查詢就開始實(shí)際執(zhí)行借和貸操作。注意每一個(gè)查詢的尾端都帶有一個(gè)mysqli_rollback(),如果查詢失敗的話,它將被激活。假設(shè)沒有查詢失敗的話,新的收支表就通過調(diào)用mysqli_commit()儲(chǔ)存到數(shù)據(jù)庫(kù)中。那時(shí)數(shù)據(jù)庫(kù)連接就被關(guān)閉。

你可以自己試一下,從Savings #1轉(zhuǎn)$500到Current #2。一旦你執(zhí)行轉(zhuǎn)帳之后,你將看到如圖表B所示的平衡表的新結(jié)果。

交易完成之后的狀況。

提示:當(dāng)然,這只是一個(gè)簡(jiǎn)單的雙命令的事務(wù)。通常,當(dāng)有許多SQL語句要一起執(zhí)行的時(shí)候,你可以用這種事務(wù)模型,一個(gè)語句的失敗對(duì)其他語句有串聯(lián)的影響。在這些情況下,你會(huì)發(fā)現(xiàn)將mysqli_query()和mysqli_rollback()的調(diào)用壓縮到一個(gè)單獨(dú)的用戶自定義的函數(shù)中,需要的時(shí)候調(diào)用它會(huì)更加簡(jiǎn)便。

正如你所看到的那樣,用PHP和MySQL執(zhí)行一個(gè)事務(wù)處理模型可以使你的MySQL數(shù)據(jù)庫(kù)對(duì)查詢執(zhí)行的錯(cuò)誤更穩(wěn)固。但是,在你開始動(dòng)手重寫代碼和使用這個(gè)模型之前,值得注意的是,事務(wù)確實(shí)會(huì)增加系統(tǒng)性能管理的消耗,所以,在實(shí)現(xiàn)這個(gè)模型之前,做一個(gè)成本效益分析始終是個(gè)好主意。

標(biāo)簽: PHP
主站蜘蛛池模板: 超碰导航 | 91免费版在线看 | 久久精品黄色 | 一级黄色大片在线 | 午夜午夜精品一区二区三区文 | 欧美日韩中文字幕 | 激情欧美一区二区三区中文字幕 | 九九在线视频 | www中文字幕在线观看 | 国产精品不卡视频 | av香港经典三级级 在线 | 九九九久久久 | 簧片毛片| 欧美日韩亚洲一区 | 中文字幕一二三区 | 91麻豆产精品久久久 | av中文在线 | 久久精品久久久 | 欧美日韩在线一区 | www.久久 | 色综合天天综合网国产成人网 | 国产精品1 | 欧美日韩精品久久 | 免费黄色在线 | 91国内外精品自在线播放 | 欧美日韩黄色一区二区 | 毛片黄色 | 久久久久久99 | 中文字幕亚洲一区二区三区 | 亚洲视频在线观看 | 91社区在线高清 | 91精品视频在线播放 | 国产日韩欧美三级 | 日韩欧美在线观看一区二区三区 | 国产激情在线视频 | a级在线免费观看 | 高清视频一区二区三区 | 天天干欧美 | 日韩欧美视频一区二区三区 | 最近的中文字幕在线看视频 | 亚洲国产精品99久久久久久久久 |