2014-05-21 160 views
3

我试图得到一个后插入触发器不回滚插入到innodb表的插入。 MyISAM似乎没有这个问题。插入触发器后MySQL - MyISAM与InnoDB

让我说明:

CREATE TABLE `testTable` (
    `id` int(10) AUTO_INCREMENT, 
    `data` text, 
    PRIMARY KEY (`id`) 
) ENGINE=InnoDB; #Engine supports transactions 

CREATE TABLE `dummyTable` (
    `id` int(10) AUTO_INCREMENT, 
    `data` text, 
    PRIMARY KEY (`id`) 
) ENGINE=InnoDB; 


DELIMITER $$ 
CREATE TRIGGER triggerTest AFTER INSERT ON `testTable` 
FOR EACH ROW 
BEGIN 
    INSERT INTO dummyTable VALUES(1, 2, 3, 4); #This will throw a column count error 
END;$$ 
DELIMITER ; 


INSERT INTO testTable(data) VALUES('This insert will be rolled back'); 
SELECT COUNT(1) FROM testTable; # 0 

如果更改的testTable发动机的MyISAM原来的插入不会被回滚(我认为)MyISAM不支持事务。

CREATE TABLE `testTable` (
    `id` int(10) AUTO_INCREMENT, 
    `data` text, 
    PRIMARY KEY (`id`) 
) ENGINE=MyISAM; #Engine does NOT support transactions 

CREATE TABLE `dummyTable` (
    `id` int(10) AUTO_INCREMENT, 
    `data` text, 
    PRIMARY KEY (`id`) 
) ENGINE=InnoDB; 

DELIMITER $$ 
CREATE TRIGGER triggerTest AFTER INSERT ON `testTable` 
FOR EACH ROW 
BEGIN 
    INSERT INTO dummyTable VALUES(1, 2, 3, 4); #This will throw a column count error 
END;$$ 
DELIMITER ; 

INSERT INTO testTable(data) VALUES('This insert will not be rolled back'); 
SELECT COUNT(1) FROM testTable; # 1 

问:是否有一种方法,使后面插入触发InnoDB表保存原始的插入,如果有在触发的错误?

+1

当然,MyISAM不会回滚原始插入,因为它无法回滚任何内容。 –

回答

4

是,不同的行为与发动机是否supports transactions or not

对于事务表,语句的故障不会导致的由语句执行的所有更改回滚。触发失败会导致语句失败,因此触发失败也会导致回滚。对于非事务性表,这种回滚无法完成,因此虽然语句失败,但在错误点之前执行的任何更改仍然有效。

可以declare a CONTINUE handlerthis specific error

DELIMITER $$ 
CREATE TRIGGER triggerTest AFTER INSERT ON `testTable` 
FOR EACH ROW 
BEGIN 
    DECLARE CONTINUE HANDLER 
     FOR SQLSTATE '21S01' -- "Column count doesn't match value count" 
     BEGIN END; -- do nothing (but continue) 
    INSERT INTO dummyTable VALUES(1, 2, 3, 4); 
END $$ 
DELIMITER ; 
0

我的一切同意到这里为止说。显然非事务性存储引擎不会回滚。但是,您可以将触发器更改为BEFORE而不是AFTER触发器,并获得与InnoDB示例I.e.中相同的结果。没有提交的更改如下:

CREATE TABLE `__testTable` (
    `id` int(10) AUTO_INCREMENT, 
    `data` text, 
    PRIMARY KEY (`id`) 
) ENGINE=MyISAM; #Engine does NOT support transactions 

CREATE TABLE `dummyTable` (
    `id` int(10) AUTO_INCREMENT, 
    `data` text, 
    PRIMARY KEY (`id`) 
) ENGINE=InnoDB; 

DELIMITER $$ 
CREATE TRIGGER triggerTest BEFORE INSERT ON `__testTable` 
FOR EACH ROW 
BEGIN 
    INSERT INTO dummyTable VALUES(1, 2, 3, 4); #This will throw a column count error 
END;$$ 
DELIMITER ; 

INSERT INTO __testTable(data) VALUES('This insert will not occur!'); 
SELECT COUNT(1) FROM __testTable; # 1