为什么MySQL会在调用回滚时插入行然后删除它?
例如使用以下代码:
declare exit handler for not found rollback;
declare exit handler for sqlwarning rollback;
declare exit handler for sqlexception
BEGIN
select last_insert_id();
rollback;
END;
START TRANSACTION;
INSERT INTO test (text) VALUES ('this_insert_works');
INSERT INTO test (id, text) VALUES (3,'this_insert_fails');
在存储过程的以下代码中,如果我执行它,然后在没有最后一行的情况下再次执行它(它将起作用),我可以看到“缺少 auto_increment ID”,因为该行被插入然后被删除。返回的 select 返回一个不存在的 ID。
如何避免这种行为?
最佳答案
您无法避免这种行为。
假设您有两个并发运行的事务,它们都将一些记录插入事务内的 test
中。它们的 id
值是多少?如果您提交一个但回滚另一个会发生什么?
唯一可行的选择是增加表的 auto_increment 计数器;由于每个事务无法看到彼此的行(但这些行确实存在于各自的事务内部),因此这是确保它们都获得唯一 ID 的唯一方法。
虽然这种行为可能看起来不受欢迎,但实际上它的存在是有充分理由的。唯一的其他选择是在事务内执行 INSERT 时锁定整个表,以防止所有其他连接向其中插入行同时上表。这对性能来说是很糟糕的。
关于MySQL 带有回滚事务 : is real?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13328297/