首先,mysqli 連接是永久連接,而mysql是非永久連接,什么意思呢?mysql連接每當第二次使用的時候,都會重新打開一個新的進程,而mysqli則只使用同一個進程,這樣可以很大程度的減輕服務器端壓力.
mysqli封裝了諸如事務等一些高級操作,同時封裝了DB操作過程中的很多可用的方法,應用比較多的地方是 mysqli的事務,比如下面的示例,代碼如下:
- $mysqli = new mysqli('localhost','root','','DB_Lib2Test');
- $mysqli->autocommit(false);//開始事物
- $mysqli->query($sql1);
- $mysqli->query($sql2);
- if(!$mysqli->errno){
- $mysqli->commit();
- echo 'ok';
- }else{
- echo 'err';
- $mysqli->rollback();
- }
在PHP中,mysqli 已經很好的封裝了mysql事務的相關操作,如下示例:
- $sql1 = "update User set ScoreCount = ScoreCount +10 where ID= '123456'";
- $sql2 = "update ScoreDetail set FScore = 300 where ID= '123456'";
- $sql3 = "insert into ScoreDetail ID,Score) values ('123456',60)";
- $mysqli = new mysqli('localhost','root','','DB_Lib2Test');
- $mysqli->autocommit(false); // 開始事務
- $mysqli->query($sql1);
- //開源代碼Vevb.com
- $mysqli->query($sql2);
- if (!$mysqli->errno) {
- $mysqli->commit();
- echo 'ok';
- } else {
- echo 'err';
- $mysqli->rollback();
- }
在這里,我們再使用 php mysql 系列函數執行事務,代碼如下:
- $sql1 = "update User set ScoreCount = ScoreCount +10 where ID= '123456'";
- $sql2 = "update ScoreDetail set FScore = 300 where ID= '123456'";
- $sql3 = "insert into ScoreDetail ID,Score) values ('123456',60)";
- $conn = mysql_connect('localhost','root','');
- mysql_select_db('DB_Lib2Test');
- mysql_query('start transaction');
- //mysql_query('SET autocommit=0');
- mysql_query($sql1);
- mysql_query($sql2);
- if (mysql_errno()) {
- mysql_query('rollback');
- echo 'err';
- } else {
- mysql_query('commit');
- echo 'ok';
- }
- // mysql_query('SET autocommit=1');
- // mysql_query($sql3);
在這里要注意.
MyISAM:不支持事務,用于只讀程序提高性能
InnoDB:支持ACID事務、行級鎖、并發
Berkeley DB:支持事務
還有一點要注意:MySQL默認的行為是在每條SQL語句執行后執行一個COMMIT語句,從而有效的將每條語句獨立為一個事務.
但往往,我們需要在使用事務的時候,是需要執行多條sql語句的,這就需要我們手動設置MySQL的autocommit屬性為0,默認為1.
同時,使用START TRANSACTION語句顯式的打開一個事務,如上面的示例,如果不這樣做,會有什么結果呢?
我們將上面第二段代碼中 //mysql_query(‘SET autocommit=0′); 和 // mysql_query($sql3); 注釋去掉,然后執行.
此時,mysql_query($sql3) 執行就不會insert到數據庫中,如果我們將 // mysql_query(‘SET autocommit=1′); 本句注釋去掉,那么mysql_query($sql3); 就會執行成功.
通常COMMIT或ROLLBACK語句執行時才完成一個事務,但是有些DDL語句等會隱式觸發COMMIT.
比如下列語句:
- ALTER FUNCTION
- ALTER PROCEDURE
- ALTER TABLE
- BEGIN
- CREATE DATABASE
- CREATE FUNCTION
- CREATE INDEX
- CREATE PROCEDURE
- CREATE TABLE
- DROP DATABASE
- DROP FUNCTION
- DROP INDEX
- DROP PROCEDURE
- DROP TABLE
- UNLOCK TABLES
- LOAD MASTER DATA
- LOCK TABLES
- RENAME TABLE
- TRUNCATE TABLE
- SET AUTOCOMMIT=1
- START TRANSACTION
我們再來舉個例子看下,代碼如下:
- $sql1 = 'create table ScoreDetail_new(id int)';
- $sql2 = 'rename table ScoreDetail to ScoreDetail_bak';
- $sql3 = 'rename table ScoreDetail_new to ScoreDetail';
- $mysqli = new mysqli('localhost','root','','DB_Lib2Test');
- $mysqli->autocommit(false);//開始事物
- $mysqli->query($sql1);
- $mysqli->query($sql2);
- $mysqli->query($sql3);
- if (!$mysqli->errno) {
- //開源代碼Vevb.com
- $mysqli->commit();
- echo 'ok';
- } else {
- echo 'err';
- $mysqli->rollback();
- }
上面的示例中,假如$sql2執行出錯了,$sql1照樣會執行的,為什么呢?因為rename在執行的時候,mysql默認會先執行commit,再執行rename.
注意:MYSQL中只有INNODB和BDB類型的數據表才能支持事務處理,其他的類型是不支持的.一般MYSQL數據庫默認的引擎是MyISAM,這種引擎不支持事務!如果要讓MYSQL支持事務,可以自己手動修改:
方法如下:1.修改c:/appserv/mysql/my.ini文件,找到skip-InnoDB,在前面加上#,后保存文件.
2.在運行中輸入:services.msc,重啟mysql服務。
3.到phpmyadmin中,mysql->show engines;(或執行mysql->show variables like 'have_%'; ),查看InnoDB為YES,即表示數據庫支持InnoDB了.
新聞熱點
疑難解答