2012-05-15 31 views
2

我期待在發生錯誤時使用事務和回滾(如重複鍵或其他)。重複鍵上的MySQL回滾

當我禁用自動提交併且出現錯誤時,即使事務不應該也提交了事務。

這裏的票面TOF我的代碼:

CREATE TABLE `Users` (
    `user_id` int(11) DEFAULT NULL, 
    PRIMARY KEY (`user_id`) 
) ENGINE=InnoDB DEFAULT CHARSET=utf8; 

CREATE TABLE `Miscs` (
    `misc_id` int(11) DEFAULT NULL, 
    PRIMARY KEY (`misc_id`) 
) ENGINE=InnoDB DEFAULT CHARSET=utf8; 

SET @@AUTOCOMMIT = 0; 

BEGIN; 
    INSERT INTO Miscs (misc_id) VALUES('1'); 
    INSERT INTO Users (user_id) VALUES('1'); 
    INSERT INTO Miscs (misc_id) VALUES('2'); 
COMMIT; 

BEGIN; 
    INSERT INTO Miscs (misc_id) VALUES('3'); 
    INSERT INTO Users (user_id) VALUES('2'); 
    INSERT INTO Miscs (misc_id) VALUES('4'); 
COMMIT; 

BEGIN; 
    INSERT INTO Miscs (misc_id) VALUES('5'); 
    INSERT INTO Users (user_id) VALUES('1'); 
    -- should stop, rollback the transaction and skip to the next/last 
    INSERT INTO Miscs (misc_id) VALUES('6'); 
COMMIT; 

-- last transaction 
BEGIN; 
    INSERT INTO Miscs (misc_id) VALUES('7'); 
    INSERT INTO Users (user_id) VALUES('4'); 
    INSERT INTO Miscs (misc_id) VALUES('8'); 
COMMIT; 

SET @@AUTOCOMMIT = 1; 

但結果是很奇怪:

Users : 
1 
2 
3 

Miscs : 
1 
2 
3 
4 
5 
6 
7 
8 

感謝您的幫助。

+0

是否在運行此表之前刪除表? –

+0

確保這些表實際上是InnoDB - 如果您將它們創建爲InnoDB,但InnoDB未安裝在服務器上,則它們將被創建爲MyISAM表 –

回答

0

在應用我會寫這樣的事情 -

START TRANSACTION 
TRY 
    INSERT 
    INSERT 
    INSERT 
    COMMIT 
CATCH 
    ROLLBACK 

但MySQL沒有的try-catch子句。我可以建議你這樣,有DECLARE EXIT HANDLER聲明 -

BEGIN 
    DECLARE EXIT HANDLER FOR SQLEXCEPTION ROLLBACK; 
    START TRANSACTION; 
     INSERT INTO Miscs (misc_id) VALUES('1'); 
     INSERT INTO Users (user_id) VALUES('1'); 
     INSERT INTO Miscs (misc_id) VALUES('2'); 
    COMMIT; 
    END; 

    BEGIN 
    DECLARE EXIT HANDLER FOR SQLEXCEPTION ROLLBACK; 
    START TRANSACTION; 
     INSERT INTO Miscs (misc_id) VALUES('3'); 
     INSERT INTO Users (user_id) VALUES('2'); 
     INSERT INTO Miscs (misc_id) VALUES('4'); 
    COMMIT; 
    END; 

    BEGIN 
    DECLARE EXIT HANDLER FOR SQLEXCEPTION ROLLBACK; 
    START TRANSACTION; 
     INSERT INTO Miscs (misc_id) VALUES('5'); 
     INSERT INTO Users (user_id) VALUES('1'); 
     -- should stop, rollback the transaction and skip to the next/last 
     INSERT INTO Miscs (misc_id) VALUES('6'); 
    COMMIT; 
    END; 

    BEGIN 
    DECLARE EXIT HANDLER FOR SQLEXCEPTION ROLLBACK; 
    START TRANSACTION; 
     INSERT INTO Miscs (misc_id) VALUES('7'); 
     INSERT INTO Users (user_id) VALUES('4'); 
     INSERT INTO Miscs (misc_id) VALUES('8'); 
    COMMIT; 
    END; 

運行從存儲過程的代碼,因爲在MySQL中是不可能在腳本中使用DECLARE處理程序。

-1

this link

一個重複鍵錯誤回滾SQL語句,如果您還沒有指定在聲明中忽略選項。