简体   繁体   English

数据库数据完整性问题

[英]Database data integrity issue

I need to make a windows service(process data every 5 mins) that 我需要做一个Windows服务(每5分钟处理一次数据)

  1. takes each record from Table1(Queue table) (MSSQL) 从Table1(Queue table)(MSSQL)中获取每个记录

  2. insert that record into various tables Table2, 3, 4, 5 (MySQL) (with Engine MyISAM) 将该记录插入各种表Table2、3、4、5(MySQL)(带有Engine MyISAM)

  3. insert data from Table1 and Table2 into Table3(Mapping table) (MSSQL) 将表1和表2中的数据插入表3(映射表)(MSSQL)

  4. delete the record from Table1 again. 再次从Table1中删除记录。

How can this be done effectively as it seems MySQL doesn't support transactions. MySQL似乎不支持事务,因此如何有效地做到这一点。 Can I use TransactionScope? 我可以使用TransactionScope吗? Or shall I manually delete the records created in previous step if error occurs in next step. 如果下一步发生错误,还是应该手动删除在上一步中创建的记录。 I am using MySQL Connector and Linq2SQL.Any suggestion will be helpful. 我正在使用MySQL Connector和Linq2SQL,任何建议都会有所帮助。 Thanks. 谢谢。

MySQL does support transactions, but not for MyISAM, you'll have to use InnoDB or likewise engine if you want transactions. MySQL确实支持事务,但不支持MyISAM,如果要进行事务,则必须使用InnoDB或类似的引擎。

There is a trick you can use and still keep MyISAM and have transactions (kind of). 您可以使用一种技巧,仍然保留MyISAM并进行事务处理(某种)。
Here's how to have your cake and eat it too :-). 这也是吃和吃蛋糕的方法:-)。

Step 1 第1步
Create a blackhole table 创建黑洞表

CREATE TABLE bh_insert_tables 
   t1.pk integer,
   t2field1 varchar(45),
   t2field2 integer,
   ....
   t3field1 integer,
   .... etc for all tables
   ) ENGINE = BLACKHOLE;

Step 2 第2步
Create a memory table to store the dummy transactions into 创建一个存储表以将虚拟事务存储到

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;

Step 3 第三步
Put a trigger on the blackhole table that will fire on insert. 将触发器放在黑洞表上,该触发器将在插入时触发。
This trigger will also add transaction support (kind of) to MyISAM. 此触发器还将为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 ;

In your insertion routine you can query table status to see which records from table1 in MSSQL where inserted successfully and which ones failed. 在插入例程中,您可以查询表status以查看MSSQL中table1中的哪些记录成功插入以及哪些记录失败。

Links: 链接:
http://dev.mysql.com/doc/refman/5.0/en/blackhole-storage-engine.html 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.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/create-trigger.html
http://dev.mysql.com/doc/refman/5.5/en/delete.html http://dev.mysql.com/doc/refman/5.5/en/delete.html
http://dev.mysql.com/doc/refman/5.5/en/declare-handler.html http://dev.mysql.com/doc/refman/5.5/zh-CN/declare-handler.html

MySQL supports transactions, just use innoDB instead of MyISAM. MySQL支持事务,只需使用innoDB代替MyISAM。

Don't forget to rollback transactions in both databases if an error occurs in either one. 如果两个数据库中的任何一个发生错误,请不要忘记在两个数据库中回滚事务。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM