【发布时间】:2016-03-05 09:31:19
【问题描述】:
我需要更新包含另一个表的 id 的表 (bigtable) 的特定列(FK 约束到 oldsmalltable)以指向另一个表上的 id(FK 约束到 newsmalltable)。基本上这就是我正在做的:
DELIMITER //
CREATE PROCEDURE updatebigtable ()
BEGIN
DECLARE EXIT HANDLER FOR SQLEXCEPTION, SQLWARNING ROLLBACK;
START TRANSACTION;
ALTER TABLE bigtable DROP FOREIGN KEY bigtable_ibfk_1,
MODIFY smalltable_id SMALLINT ;
UPDATE bigtable SET smalltable_id=CASE smalltable_id
WHEN 1 THEN 1592
WHEN 2 THEN 1593
WHEN 3 THEN 1602
...
ELSE 0
END;
ALTER TABLE bigtable ADD CONSTRAINT bigtable_ibfk_1
FOREIGN KEY(smalltable_id) REFERENCES newsmalltable(id);
COMMIT;
END//
DELIMITER ;
CALL updatebigtable();
DROP PROCEDURE updatebigtable;
我需要确保如果由于某种原因新的外键约束失败(例如,对于不同类型的列,错误将出现在最后一个 alter table 语句中),UPDATE 和第一个 ALTER TABLE 应该也可以回滚,即它们应该保持最初的状态。
根据MySQL documentation,通过使用START TRANSACTION,该事务的自动提交模式被禁用,这将不允许:
一旦您执行更新(修改)表的语句,MySQL 就会将更新存储在磁盘上以使其永久化。
我只发现这个问题与我的关系微乎其微:
How can I use transactions in my MySQL stored procedure?
如果我提到的错误发生在事务内部,则前面的语句已经执行并且更新是“永久在磁盘上完成”...
我还尝试在创建过程之前放置SET autocommit=0;,但行为仍然相同......我错过了什么吗?或者这是 MySQL 事务回滚的预期行为?
如果有什么不同,我使用的是 MySQL v.5.6.17。
【问题讨论】:
标签: mysql database transactions rollback