在Java中的游戏服务器代码中,我将客户端数据拆分为多个表,以方便将来添加新内容。
现在我有以下表格
name
表包含id
和name
列。
auth
表包含id
列和password
列。
id
和auth
表上的inventory
列在name
的{{1}}列上有外键约束。
在创建新客户端时,我插入id
表,获取生成的id,并将其余数据插入到单独的insert语句中的其他表中,但所有这些都在一个事务中。
问题是,当我插入name
表时,由于auth
中的外键检查而失败,因为我还没有提交它。有没有更好的方法来解决这个问题,而无需每次插入?
答案 0 :(得分:2)
除非您{strong>插入父表后rollback
,否则子表将允许在父项中插入与新插入的行对应的行表 表即使您在插入父表后没有commit
。 所以这几乎不用担心。 DML
操作的影响会一直持续到下一个 rollback
,并且在 commit
时变为永久性声明。因此,如果在父表中的rollback
操作之后没有显式地insert
,子表将始终允许与父表中的所有行相对应的插入,而不管任何commit
操作。
即使FOREIGN_KEY_CHECKS=1
。
答案 1 :(得分:1)
我对此问题进行了一些研究,以找出解决方案。我有同样的问题,在同一事务中添加父和子时,外键约束引发错误。
问题及其解决方法不是代码,而是数据库。问题是可延迟的限制。下面的2个链接讨论它们的Oracle。底部2讨论了SQLServer和MySQL。我的一些研究表明,MySQL会自动推迟;下面的链接表明它没有。
从我正在阅读的内容中,约束通常会立即进行测试并失败。通过推迟约束,它将测试完成的提交。
http://docs.oracle.com/cd/E11882_01/server.112/e25789/datainte.htm#CNCPT88892
http://docs.oracle.com/cd/B10500_01/server.920/a96524/c22integ.htm#4666
How to define a deferred constraint in MySQL
Does SQL Server allow constraint violations in a transaction as long as it's not committed yet?
答案 2 :(得分:-2)
如果您仍然遇到问题,作为临时修复,您可以暂时禁用外键检查以通过
SET FOREIGN_KEY_CHECKS=0;
确保在
之后重新启用SET FOREIGN_KEY_CHECKS=1;