为什么我在单个自引用表的事务中获得MySQL外键插入约束违规?

时间:2013-09-25 01:42:03

标签: mysql transactions foreign-keys constraints

我有一个自我引用的表格,如:

  

“ClassGroup”的表架构是:
  Id String,主键
  名称字符串,
  ParentClassGroup String,外键(指此表中的“id”)

以下交易将按预期成功:

  

SET AUTOCOMMIT = 0;
  开始交易;
  INSERT INTO CLASSGROUP(x_id,x_name,x_parentclassgroup_x_id)值(“id1”,“cg1”,null);
  INSERT INTO CLASSGROUP(x_id,x_name,x_parentclassgroup_x_id)值(“id2”,“cg2”,“id1”);
  INSERT INTO CLASSGROUP(x_id,x_name,x_parentclassgroup_x_id)值(“id3”,“cg3”,null);
  提交;

但以下交易将失败:

  

SET AUTOCOMMIT = 0;
  开始交易;
  INSERT INTO CLASSGROUP(x_id,x_name,x_parentclassgroup_x_id)值(“id2”,“cg2”,“id1”);
  INSERT INTO CLASSGROUP(x_id,x_name,x_parentclassgroup_x_id)值(“id1”,“cg1”,null);
  INSERT INTO CLASSGROUP(x_id,x_name,x_parentclassgroup_x_id)值(“id3”,“cg3”,null);
  提交;

错误日志:

  

0 08:14:29 INSERT INTO CLASSGROUP(x_id,x_name,x_parentclassgroup_x_id,x_talend_timestamp)值(“id2”,“cg2”,“id1”,123)错误代码:1452。无法添加或更新子行:外键约束失败(hier_master.classgroup,CONSTRAINT FKC0C64078BC2ACBF FOREIGN KEY(x_parentclassgroup_x_id)REFERENCES classgroup(x_id))

我的问题是: MySQL服务器不够聪明,不知道第二次插入应该在第一次插入之前完成,因为带有“id2”的记录是指带有“id1”的记录吗?由于插入顺序错误,是否会出现故障?那么像Oracle这样的其他数据库中的事务呢? 非常感谢您的见解和帮助!

2 个答案:

答案 0 :(得分:0)

这是预期的。在我测试的所有RDBMS(Oracle,MySQL,H2)中,没有RDBM会根据数据依赖性对事务中的sql语句进行重新排序,rdbms将按照用户在trasaction中提供的顺序执行每个sql语句。因此,您有责任通过在事务中正确排序sql插入语句来确保数据依赖性得到解决。

答案 1 :(得分:0)

在MySQL中有一项称为延迟约束检查的规定。

它的作用是,它执行对用户执行的所有对表的操作,然后检查约束违规,而不是在每个insert语句之后检查约束违规的常规方法。

我不知道延迟约束检查的确切语法,但我相信您可以通过互联网轻松找到它。 我希望这有帮助! :)