我有一个自我引用的表格,如:
“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这样的其他数据库中的事务呢? 非常感谢您的见解和帮助!
答案 0 :(得分:0)
这是预期的。在我测试的所有RDBMS(Oracle,MySQL,H2)中,没有RDBM会根据数据依赖性对事务中的sql语句进行重新排序,rdbms将按照用户在trasaction中提供的顺序执行每个sql语句。因此,您有责任通过在事务中正确排序sql插入语句来确保数据依赖性得到解决。
答案 1 :(得分:0)
在MySQL中有一项称为延迟约束检查的规定。
它的作用是,它执行对用户执行的所有对表的操作,然后检查约束违规,而不是在每个insert语句之后检查约束违规的常规方法。
我不知道延迟约束检查的确切语法,但我相信您可以通过互联网轻松找到它。 我希望这有帮助! :)