[英]MySQL After Insert Trigger - MyISAM vs InnoDB
我试图得到一个插入后触发器,以便不回滚对innodb表执行的插入操作。 MyISAM似乎没有这个问题。
让我说明一下:
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表的插入触发器之后保留原始插入?
是的,不同的行为与引擎是否支持事务有关:
对于事务表,语句失败应导致回滚语句执行的所有更改。 触发器失败会导致语句失败,因此触发器失败也会导致回滚。 对于非事务性表,无法执行此类回滚,因此尽管语句失败,但在错误点之前执行的任何更改仍然有效。
您可以为此特定错误 声明CONTINUE
处理程序 :
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 ;
我同意到目前为止所说的一切。 显然非事务性存储引擎不会回滚。 但是,您可以将触发器更改为BEFORE而不是AFTER触发器,并获得与InnoDB示例中相同的结果,即未提交的更改如下:
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
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.