为什么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。
如何避免此行为?
答案 0 :(得分:3)
你无法避免这种行为。
假设您有两个同时运行的事务,并且它们都会在事务内部test
中插入一些记录。他们的id
值是多少?如果您提交一个但回滚另一个会发生什么?
唯一可行的选择是增加表的auto_increment计数器;由于每个事务都看不到彼此的行(但行确实存在于各自的事务中),这是确保它们都获得唯一ID的唯一方法。
虽然这种行为可能看起来不受欢迎,但实际上这是有充分理由的。唯一的另一种选择是在事务内部执行INSERT
时锁定整个表,防止每个其他连接将行插入到该表中同时。这对表现来说太糟糕了。