2013-04-25 189 views
2

mysql documentation指出某些語句會在事務期間導致隱式提交。例如:如何防止mysql隱式提交

CREATE TABLE foo (bar INT); 
START TRANSACTION; 
INSERT INTO foo VALUES (1); 
CREATE TEMPORARY TABLE mumble like foo; 
ALTER TABLE mumble modify bar INT UNSIGNED; 
ROLLBACK; 
SELECT * FROM foo; 

回滾之後,我得到一個排回從富 - 文檔實際上說的ALTER TABLE不應該因爲如果你使用臨時關鍵字隱式提交,但ALTER TABLE TEMPORARY是無效的語法,並刪除臨時表不會導致暗示提交,所以我懷疑只有一個錯誤(至少5.5.29)

在任何情況下,我想要做的是告訴mysql永遠不隱式提交,但是如果給出了會導致隱式提交的命令,則會失敗/回滾。

我懷疑沒有辦法做到這一點,環顧四周,但我希望我錯了。希望這裏有人知道:)

回答

1

,我剛剛成功地嘗試了另一種哈克的方法是獲得通過具體的MySQL命令創建表的DDL

SHOW CREATE TABLE `tableName` 

然後做一些正則表達式魔術和起草新DDL查詢它將根據原始表創建一個臨時表,將所有alter table更改合併到create table中。

在我的基於PHP的項目中,我做了以下操作來爲臨時表添加唯一索引。它做了訣竅,在事務中間不再發生隱式提交。這裏

$createDDL = ... get from SHOW CREATE TABLE `tableName` 
$nr = 0; 
$createDDL = preg_replace("/CREATE TABLE `$tableName` \(/", "CREATE TEMPORARY TABLE `$tmpName` (\nUNIQUE `ukey-1` ($uniqCols),", $createDDL, -1, $nr); 
if (!$nr) 
    throw new Exception("CREATE TABLE replacement error. No reps made."); 
mysqli_query($con, $createDDL); 

編輯順便說一些bug(功能)的報告(多年以來)。在第一個,你可以看到的狀態下響應(約會至2006年):因爲這種行爲是一樣的Oracle數據庫中,這是一致的一個...

也許功能請求「垃圾郵件活動」應該啓動此功能請求恢復!

+0

正確,這是一種解決方法,我最終做了類似的事情 - 真的希望有某種方式來做到這一點 - 但它似乎從錯誤報告他們不打算修復它。感謝您找到這些。 – 2013-05-30 19:59:29

0

至少在MySQL 5.5.19中,你是對的。文檔聲明ALTER TEMPORARY TABLE不會執行顯式提交,但會對TEMPORARY關鍵字執行MySQL扼流。

我能想到的兩種可能的解決方法:

解決方法1:

使用一個新的臨時表中地方ALTER

CREATE TABLE foo (bar INT); 
START TRANSACTION; 
INSERT INTO foo VALUES (1); 
CREATE TEMPORARY TABLE mumble LIKE foo; 
CREATE TEMPORARY TABLE mumble2 (bar INT UNSIGNED) SELECT * FROM mumble; 
ROLLBACK; 
SELECT * FROM foo; 

的最後一條語句產生以下輸出:

Empty set (0.00 sec) 

不幸的是,沒有辦法將mumble2重命名爲mumble,因爲RENAME不允許用於臨時表,並且ALTER mumble2 RENAME mumble隱式提交。

解決方法2:

不要使用臨時表,而是產生一個子進程來運行,將導致隱式的命令提交:

方法1:

CREATE TABLE foo (bar INT); 
START TRANSACTION; 
INSERT INTO foo VALUES (1); 

過程2(並使用到MySQL的不同連接):

CREATE TABLE mumble LIKE foo; 
ALTER TABLE mumble modify bar INT UNSIGNED; 

過程1:

ROLLBACK; 
SELECT * FROM foo; 
DROP TABLE IF EXISTS mumble; 
+0

這個解決方法對於我的示例來說似乎很合理,但我真正想要的是解決此問題的更一般的解決方案。我不認爲mysql應該在事務中隱式地提交 - 或者如果它要做的話,應該有某種方式(安全模式/例如)告訴它回滾和出錯,而不是這樣做。 – 2013-04-25 20:22:37

+0

我同意。文檔建議在執行涉及'TEMPORARY'表的每個*每個DDL語句時,MySQL不應該暗示提交,因此可能已經在更新的版本中解決了這個問題。讓我們交叉手指! – 2013-04-25 20:31:19

+0

不幸的是沒有固定在5.6.11,我不確定是否打開了一個錯誤。我還沒有找到一種方法來禁用隱式提交... – basos 2013-05-22 11:40:51