在群集模式下添加子表的行时,H2参照完整性冲突

时间:2015-10-21 09:34:05

标签: sql jdbc h2 corruption

TL; DR:未发生违规时触发参照完整性违规 我在群集模式下运行H2,有2个节点 我在H2数据库(v1.4.189)中有两个表,父表和子表。子项包含父表行的ID的外键。 通常,在子表中插入行时,我不会遇到任何错误 但过了一段时间,我在插入时遇到了这个错误:

Referential integrity constraint violation: "CONSTRAINT_1FE: PUBLIC.CHILD FOREIGN KEY(fkey)
REFERENCES PUBLIC.PARENT(ID) (86)"

奇怪的是,成功插入了产生错误的INSERT INTO数据,并且没有外键约束违规!

我已尝试记录重现错误的确切步骤,但使用新数据库时,错误永远不会发生:

drop table CHILD;
drop table PARENT;
create table CHILD(id int auto_increment, name varchar(255), fkey int);
create table PARENT(id int auto_increment, name varchar(255));

ALTER TABLE `CHILD` ADD FOREIGN KEY (fkey) REFERENCES `PARENT` (`id`);

insert into PARENT(name) values('hello');
insert into PARENT(name) values('world');
select * from PARENT; 


insert into CHILD(name, fkey) values('hello', 1); 
-- this works for a while, but someday the Referential integrity error 
-- will pop, but data will be added anyway (wtf?)
insert into CHILD(name, fkey) values('world', 2);

在数据库上,我只做一些简单的事情,比如选择,插入,删除......

有趣的事实是,在此错误发生一次后,我得到另一个奇怪的错误:当删除(或更新)CHILD表的行时,DELETE FROM或UPDATE函数总是返回0,即使某些行已被删除。 ..(也是jdbc executeUpdate()总是返回0)

数据库在某些时候是否已损坏?

我发现修复此错误的唯一工作方法是删除所有表并重新创建表,这不是我想要做的。

2 个答案:

答案 0 :(得分:0)

H2主要开发人员thomas mueller在github上回答了这个问题:

  

这是已记录的群集功能限制之一,请参阅   以及“聚类算法和局限性”:“使用自动增量和   当前不支持标识列。”

     

恐怕很难修复。我建议不要使用群集   为此功能。对它的支持可能会在   未来。我希望可以使用新的群集/自动故障转移功能   添加,但这将需要一些时间。

     

但这可能对您很有趣:https://github.com/shesse/h2ha

请参见issue on github

我设法使其正常工作:使用序列并两次插入:
-获取此表序列的nextval,例如: nextid = select childsequence.nextval from dual
-然后执行您的INSERT INTO child并指定ID nextid

答案 1 :(得分:0)

由于未找到外键而引发异常,您需要首先插入相关数据。

示例:

// Execute below query first
INSERT INTO root_table VALUES (value1, value2)
// Execute below query after root_table
INSERT INTO sub_Table VALUES (value1, value2, FK_root_ID)