MySQL確實支持事務,但不支持MyISAM,如果您想要事務,您將不得不使用InnoDB或類似的引擎。
有一個技巧,你可以使用並仍然保持MyISAM和交易(種)。
以下是如何擁有你的蛋糕和吃它:-)。
步驟1
創建黑洞表
CREATE TABLE bh_insert_tables
t1.pk integer,
t2field1 varchar(45),
t2field2 integer,
....
t3field1 integer,
.... etc for all tables
) ENGINE = BLACKHOLE;
步驟2
創建一個存儲器表到僞交易存儲到
CREATE TABLE my_rollback
id unsigned integer auto_increment primary key,
last_insert integer not null,
tablename varchar(15) not null,
index last_insert using hash ('last_insert'),
index tablename using hash ('tablename')
) ENGINE = MEMORY;
CREATE TABLE status
id unsigned integer auto_increment primary key,
insert_id integer not null,
success boolean not null,
index insert_id using hash ('insert_id')
) ENGINE = MEMORY;
步驟3
在黑洞桌上放置一個觸發器,將在插入時觸發。
這個觸發器還會將事務支持(種類)添加到MyISAM。
DELIMITER $$
CREATE TRIGGER ai_bh_insert_each AFTER INSERT ON bh_insert FOR EACH ROW
BEGIN
DECLARE table1ID integer;
DECLARE error boolean;
DECLARE CONTINUE HANDLER FOR SQLEXCEPTION
BEGIN
SET error = TRUE;
END;
SET error = FALSE;
INSERT INTO table2 (field1, field2, field3) VALUES (NEW.t2field1, NEW.t2field2, NEW.t2field3);
IF not(error) THEN BEGIN
INSERT INTO my_rollback (last_insert, tablename) VALUES (LAST_INSERT_ID(), 'table2');
INSERT INTO table3 (field1,field2) VALUES (NEW.t3field1, NEW.t3field2);
END; END IF;
IF NOT(error) THEN BEGIN
INSERT INTO my_rollback (last_insert, tablename) VALUES (LAST_INSERT_ID(), 'table3');
INSERT INTO table4 .......
END; END IF;
IF error THEN BEGIN /*do_rollback*/
DELETE table2 FROM table2
INNER JOIN my_rollback ON table2.id = my_rollback.last_insert
WHERE my_rollback.tabelname = 'table2';
DELETE table2 FROM table2 .......
INSERT INTO status (insert_id, success) VALUES (NEW.pk, false);
END;
ELSE BEGIN
INSERT INTO status (insert_id, success) VALUES (NEW.pk, true);
END; END IF;
/*Clear my_rollback for the next insert*/
DELETE FROM my_rollback WHERE id IS NOT NULL;
END $$
DELIMITER ;
在你插入程序就可以查詢表status
看到這裏插入成功,哪些失敗了,從表1中記錄MSSQL。
鏈接:
http://dev.mysql.com/doc/refman/5.0/en/blackhole-storage-engine.html
http://dev.mysql.com/doc/refman/5.0/en/triggers.html
http://dev.mysql.com/doc/refman/5.5/en/create-trigger.html
http://dev.mysql.com/doc/refman/5.5/en/delete.html
http://dev.mysql.com/doc/refman/5.5/en/declare-handler.html
所有這些以避免innoDB?這就是這個,令人印象深刻!我認爲。 – Ariel
@Ariel,你應該總是使用InnoDB,它是MyISAM以外的光年,但是如果你不能使用它,你需要變得富有創造力,儘管可以投票:-)。 – Johan
+1 @Johan,非常有幫助。謝謝。 – Prazanna