Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/70.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 在群集模式下添加子表行时发生H2引用完整性冲突_Sql_Jdbc_H2_Corruption - Fatal编程技术网

Sql 在群集模式下添加子表行时发生H2引用完整性冲突

Sql 在群集模式下添加子表行时发生H2引用完整性冲突,sql,jdbc,h2,corruption,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

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);
在数据库上,我只做一些简单的事情,比如选择、插入、删除

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

数据库是否在某个时候损坏


我找到的唯一解决此错误的方法是删除所有表并重新创建表,这不是我想要做的。

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

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

恐怕很难修理。我建议不要使用集群 正是出于这个原因。对它的支持可能会在中删除 未来。我希望可以使用新的群集/自动故障切换功能 补充,但这需要一些时间

但这可能会让你感兴趣:

我设法让它工作:使用序列并插入两次:
-获取此表序列的nextval,例如:nextid=
从dual中选择childsequence.nextval


-然后执行
插入到子项中
并指定id
nextid

由于找不到外键而引发异常,您需要先插入依赖数据

例如:

// 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)

最有可能的是,
auto_increment
生成的值与您在子表的insert语句中硬编码的值不同。这不是问题所在。我提供了这些步骤来帮助理解这个问题。无论如何,在我的应用程序中,我总是在插入到子表之前检查外键值是否存在。不相关,但是:“我总是在插入之前检查外键值是否存在”-这完全是浪费时间,因为这正是FK约束的目的。您应该只处理错误,而不是在代码中重复FK约束检查。但是我更倾向于相信H2,而不是你声称你的代码是正确的。我能想到的唯一可能的事情是:H2V1.4仍然被标记为“beta”版本。你试过V1.3吗?你完全正确!我编码这个“检查”是因为我首先遇到了描述的错误,它提供了一个解决方法(如果检查正常+获取引用完整性冲突=一切正常)。有趣的是,现在我已经删除了所有的表,并重新创建了数据库的结构(与以前完全相同),我不能重现这个问题(也不能用v1.3测试)。。。然而当您有一个将重新创建您的问题的问题时,请回答您的问题。没有这些,任何人所能做的就是猜测你的问题可能是什么。