数据库数据完整性问题

时间:2011-06-23 08:41:33

标签: mysql sql-server-2008 database-connection

我需要制作一个Windows服务(每5分钟处理一次数据)

  1. 从Table1(队列表)(MSSQL)

  2. 获取每条记录
  3. 将该记录插入各种记录中 表表2,3,4,5(MySQL)(带 引擎MyISAM)

  4. 从Table1和Table2插入数据 到表3(映射表)(MSSQL)

  5. 再次从Table1中删除记录。

  6. 如何有效地完成这项工作,因为MySQL似乎不支持交易。 我可以使用TransactionScope吗?或者,如果下一步发生错误,我是否应手动删除上一步中创建的记录。我正在使用MySQL Connector和Linq2SQL.Any建议会有所帮助。感谢。

2 个答案:

答案 0 :(得分: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以查看MSSQL中table1中哪些记录成功插入以及哪些记录失败。

<强>链接:
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

答案 1 :(得分:-1)

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

如果任何一个数据库发生错误,请不要忘记在两个数据库中回滚事务。