2011-06-23 60 views
1

我需要一個Windows服務(每5分鐘的過程數據)數據庫的數據完整性問題

  1. 需要從表1(隊列表)(MSSQL)每個記錄

  2. 插入記錄到各種 表表2,3,4,5(MySQL的)(與 引擎的MyISAM)

  3. 從Table 1和Table 插入數據到表3(表映射)(MSSQL)

  4. 再次從表1中刪除記錄。

這怎麼能有效地完成,因爲它似乎MySQL不支持事務。 我可以使用TransactionScope嗎?或者,如果在下一步中發生錯誤,我應手動刪除在上一步中創建的記錄。我正在使用MySQL連接器和Linq2SQL.Any建議將會有所幫助。謝謝。

回答

1

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

+0

所有這些以避免innoDB?這就是這個,令人印象深刻!我認爲。 – Ariel

+0

@Ariel,你應該總是使用InnoDB,它是MyISAM以外的光年,但是如果你不能使用它,你需要變得富有創造力,儘管可以投票:-)。 – Johan

+0

+1 @Johan,非常有幫助。謝謝。 – Prazanna

-1

MySQL支持事務,只需使用innoDB而不是MyISAM。

如果任何一個數據庫中發生錯誤,請不要忘記在兩個數據庫中回滾事務。

+0

MySQL數據庫已經在生產。他們不會允許我們對其進行任何修改。 – Prazanna