2010-02-17 114 views
3

我已經制作了一個數據庫包裝器,它帶有圍繞PDO系統的額外功能(是的,我知道一個包裝器的包裝器,但它只是帶有一些額外功能的PDO)。但我注意到了一個問題。事務回滾不起作用

如下因素不起作用像它應該是:

<?php 
var_dump($db->beginTransaction()); 

$db->query(' 
INSERT INTO test 
(data) VALUES (?) 
;', 
array(
    'Foo' 
) 
); 
print_r($db->query(' 
SELECT * 
FROM test 
;' 
)->fetchAll()); 

var_dump($db->rollBack()); 

print_r($db->query(' 
SELECT * 
FROM test 
;' 
)->fetchAll()); 
?> 

後續代碼var_dump的表明的BeginTransaction和回滾功能返回true,所以沒有錯誤。

我預計第一個print_r調用會顯示N個項目的數組,第二個調用顯示N-1個項目。但事實並非如此,它們都顯示相同數量的項目。

我的$ DB->查詢(< SQL>,<值>)調用沒有別的然後$ pdo->準備(< SQL>) - >執行(<值>)(額外的錯誤處理ofcourse)。

所以我認爲或MySQL的交易系統不起作用,或者PDO的實施不起作用或者我看到有什麼問題。

有誰知道問題是什麼?

回答

12

檢查您的數據庫類型是否等於innoDB。總之,你必須檢查你的數據庫是否支持事務。

+0

這是解決方案。但奇怪的是,爲什麼pdo在MyISAM上使用事務時不會返回false(或拋出異常)......奇怪。 – VDVLeon 2010-02-17 15:18:04

+0

您仍然可以與MyISAM進行交易 - 它無法回滾。這意味着交易是無效的。您甚至可以在同一個事務中混合使用事務性和非事務性表 - 這隻會讓人感到困惑。通常(在大多數情況下),你會希望所有的表都是innodb。 – MarkR 2010-02-17 22:02:54

2

MySQL不支持MyISAM表類型上的事務,這不幸是默認的表類型。

如果您需要事務處理,則應切換到InnoDB表類型。

4

兩個可能的問題:

  1. 該表的MyISAM不支持事務。使用InnoDB。

  2. 檢查以確保自動提交是關閉的。

http://www.php.net/manual/en/pdo.transactions.php

+0

如果我開始顯式事務,爲什麼自動提交應該關閉? – 2013-09-05 13:55:30

3

我進入這個作爲一個答案,作爲一個評論是小到包含以下內容:

PDO只是周圍的各種低級別的數據庫接口庫的包裝。如果低級圖書館不抱怨,PDO也會。由於MySQL支持事務處理,所以沒有事務操作會返回語法錯誤或其他。您可以使用事務中的MyISAM表,但他們所做的任何操作都將完成,就好像自動提交仍然活躍:

mysql> create table myisamtable (x int) engine=myisam; 
Query OK, 0 rows affected (0.00 sec) 

mysql> create table innodbtable (x int) engine=innodb; 
Query OK, 0 rows affected (0.00 sec) 

mysql> start transaction; 
Query OK, 0 rows affected (0.00 sec) 

mysql> insert into myisamtable (x) values (1); 
Query OK, 1 row affected (0.00 sec) 

mysql> insert into innodbtable (x) values (2); 
Query OK, 1 row affected (0.00 sec) 

mysql> rollback; 
Query OK, 0 rows affected, 1 warning (0.00 sec) 

mysql> select * from myisamtable; 
+------+ 
| x | 
+------+ 
| 1 | 
+------+ 
1 row in set (0.00 sec) 

mysql> select * from innodbtable; 
Empty set (0.00 sec) 

mysql> 

正如你所看到的,即使交易活躍,並進行了一些動作在MyISAM表上,沒有錯誤被拋出。

+0

好點。對我來說似乎邏輯。 – VDVLeon 2010-02-18 16:26:23

+1

查詢OK,0行受影響,1警告(0.00秒) 也許你可以檢索他們是否有任何警告 – oneat 2010-02-18 18:32:04

+1

好點。下面是我重做測試插入/回滾後的警告輸出: 「某些非事務性更改的表無法回滾」 – 2010-02-18 18:58:39