【轉】phpmysql事務詳解

吞吞吐吐的發表於2017-09-07

原文轉載:http://www.gosoa.com.cn/php-mysql%E4%BA%8B%E5%8A%A1%E8%AF%A6%E8%A7%A3

 

在說php mysql事務之前,可以先了解下 php mysql與mysqli 區別

在PHP中,mysqli 已經很好的封裝了mysql事務的相關操作。如下示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
$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);
$mysqli->query($sql2);
if(!$mysqli->errno){
  $mysqli->commit();
  echo `ok`;
}else{
 echo `err`;
  $mysqli->rollback();
}

在這裡,我們再使用 php mysql 系列函式執行事務。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
$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);

在這裡要注意,

  1. MyISAM:不支援事務,用於只讀程式提高效能
  2. InnoDB:支援ACID事務、行級鎖、併發
  3. 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。 

比如下列語句

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
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

我們再來舉個例子看下。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
$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){
  $mysqli->commit();
  echo `ok`;
}else{
 echo `err`;
  $mysqli->rollback();
}

在上面的示例中,假如$sql2執行出錯了,$sql1照樣會執行的。為什麼呢? 

因為rename在執行的時候,mysql預設會先執行commit,再執行rename。

宣告:如有轉載本博文章,請註明出處。您的支援是我的動力!文章部分內容來自網際網路,本人不負任何法律責任。

本文轉自bourneli部落格園部落格,原文連結:http://www.cnblogs.com/bourneli/articles/2553947.html,如需轉載請自行聯絡原作者


相關文章