【问题标题】:Circle foreign key reference insert MySQL and transaction rollback圈外键引用插入MySQL和事务回滚
【发布时间】:2012-04-08 21:03:26
【问题描述】:

我正在使用 MySQL 和 InnoDB,最近遇到了一些问题。

这是我正在尝试运行的语句(我删除了一些个人详细信息):

START TRANSACTION;

SET FOREIGN_KEY_CHECKS = 0;
INSERT INTO zdb_user (U_DateStart, U_Main_Adres_ID)
VALUES ('2012-04-08', 0);
SET FOREIGN_KEY_CHECKS = 1;

SET @newUID = LAST_INSERT_ID();

INSERT INTO zdb_adres (A_User_ID, A_Zipcode, A_Number)
VALUES (@newUID, '1234AB', 12);

UPDATE zdb_user SET U_Main_Adres_ID = LAST_INSERT_ID() WHERE User_ID = @newUID;

COMMIT;

问题是我使用的是“圆形”外键引用。我现在通过禁用密钥检查绕过了它。

zdb_adres.A_User_ID 需要有效的User_ID。而zdb_user.U_Main_Adres_ID 需要一个有效的Adres_ID,但我没有任何一个。现在,只要可以实际创建 zdb_user 中的记录,这一切都可以正常工作。但是有几个限制可能导致它无法创建。

我认为如果出现错误,事务会停止,但在运行一个简单的测试后,我发现这根本不是真的。因此我去谷歌搜索,我发现了几个解决方案,例如:

DECLARE EXIT HANDLER FOR SQLEXCEPTION, SQLWARNING, NOT FOUND BEGIN ROLLBACK; CALL ERROR_ROLLBACK_OCCURRED; END;

太糟糕了,它不起作用,当我在 START TRANSACTION; 之后添加它时收到语法错误:

1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'DECLARE EXIT HANDLER FOR SQLEXCEPTION, SQLWARNING, NOT FOUND BEGIN ROLLBACK' at line 1

有人知道问题出在哪里吗?

【问题讨论】:

  • 为什么不给自己一个受伤的世界,摆脱循环引用呢?一个 address_User 表将摆脱所有这些痛苦,这极大地违反了 KISS 原则。
  • 那会更简单吗?它首先不能确保数据的有效性,它会引入多对多的可能性,这不是这样的。这是一对多的关系。
  • 问一个关于如何避免循环引用的问题,我很乐意尝试回答。鉴于我现在不知道你对模型的所有标准,我不能肯定,但就个人而言,我会竭尽全力避免你现在所处的裂缝。
  • 解决方案很简单,删除使 id 可以为空,一切正常。但是,如果该字段为 NULL,则会出现错误。所以它仍然必须在一个错误回滚的事务中。
  • 那不是一个解决方案吗?在 Userid 上具有唯一键的 Address_user 是我的第一个想法....

标签: mysql sql transactions foreign-keys innodb


【解决方案1】:

摆脱禁用外键检查的唯一方法是将U_Main_Adres设为可空。

【讨论】:

    猜你喜欢
    • 2012-08-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-24
    • 2013-11-22
    • 1970-01-01
    • 2020-02-28
    • 1970-01-01
    相关资源
    最近更新 更多