MySQL 重复键回滚

标签 mysql transactions innodb commit rollback

我期待在出现错误时使用事务和回滚(例如重复键或其他)。

当我禁用自动提交并且出现错误时,事务已被提交,即使它们不应该提交。

这是我的代码:

CREATE TABLE `Users` (
  `user_id` int(11) DEFAULT NULL,
  PRIMARY KEY (`user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

CREATE TABLE `Miscs` (
  `misc_id` int(11) DEFAULT NULL,
  PRIMARY KEY (`misc_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

SET @@AUTOCOMMIT = 0;

BEGIN;
    INSERT INTO Miscs ( misc_id ) VALUES('1');
    INSERT INTO Users ( user_id ) VALUES('1');
    INSERT INTO Miscs ( misc_id ) VALUES('2');
COMMIT;

BEGIN;
    INSERT INTO Miscs ( misc_id ) VALUES('3');
    INSERT INTO Users ( user_id ) VALUES('2');
    INSERT INTO Miscs ( misc_id ) VALUES('4');
COMMIT;

BEGIN;
    INSERT INTO Miscs ( misc_id ) VALUES('5');
    INSERT INTO Users ( user_id ) VALUES('1');
    -- should stop, rollback the transaction and skip to the next/last
    INSERT INTO Miscs ( misc_id ) VALUES('6');
COMMIT;

-- last transaction
BEGIN;
    INSERT INTO Miscs ( misc_id ) VALUES('7');
    INSERT INTO Users ( user_id ) VALUES('4');
    INSERT INTO Miscs ( misc_id ) VALUES('8');
COMMIT;

SET @@AUTOCOMMIT = 1;

但结果很奇怪:

Users :
1
2
3

Miscs :
1
2
3
4
5
6
7
8

感谢您的帮助。

最佳答案

在应用程序中我会写这样的东西 -

START TRANSACTION
TRY
  INSERT
  INSERT
  INSERT
  COMMIT
CATCH
  ROLLBACK

但是MySQL没有TRY-CATCH子句。我可以这样建议你,使用 DECLARE EXIT HANDLER声明-

  BEGIN
    DECLARE EXIT HANDLER FOR SQLEXCEPTION  ROLLBACK;
    START TRANSACTION;
      INSERT INTO Miscs ( misc_id ) VALUES('1');
      INSERT INTO Users ( user_id ) VALUES('1');
      INSERT INTO Miscs ( misc_id ) VALUES('2');
    COMMIT;
  END;

  BEGIN
    DECLARE EXIT HANDLER FOR SQLEXCEPTION  ROLLBACK;
    START TRANSACTION;
      INSERT INTO Miscs ( misc_id ) VALUES('3');
      INSERT INTO Users ( user_id ) VALUES('2');
      INSERT INTO Miscs ( misc_id ) VALUES('4');
    COMMIT;
  END;

  BEGIN
    DECLARE EXIT HANDLER FOR SQLEXCEPTION  ROLLBACK;
    START TRANSACTION;
      INSERT INTO Miscs ( misc_id ) VALUES('5');
      INSERT INTO Users ( user_id ) VALUES('1');
      -- should stop, rollback the transaction and skip to the next/last
      INSERT INTO Miscs ( misc_id ) VALUES('6');
    COMMIT;
  END;

  BEGIN
    DECLARE EXIT HANDLER FOR SQLEXCEPTION  ROLLBACK;
    START TRANSACTION;
      INSERT INTO Miscs ( misc_id ) VALUES('7');
      INSERT INTO Users ( user_id ) VALUES('4');
      INSERT INTO Miscs ( misc_id ) VALUES('8');
    COMMIT;
  END;

从存储过程运行此代码,因为在 MySQL 中不可能在脚本中使用 DECLARE 处理程序。

关于MySQL 重复键回滚,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10602866/

相关文章:

php - mysql查询中Where子句中的未知列

mysql - group_concat mysql子查询只返回一项

php - mysql如何合并一个表中相似的记录

mysql - 错误号 : 150 "Foreign key constraint is incorrectly formed" Nothing helps

php - 在使用 php 成功进行 paypal 货币交易后提交表单

sql-server - 事务可以在同一个 SQL Server 中跨多个数据库工作吗?如果是,这是分布式事务吗?

.net - SQL中默认的最大事务超时是多少

mysql - 我是否需要为 DBIx::Class belongs_to 关系手动创建索引

MySQL:InnoDB 缓冲区使用量持续增长

主动/被动拓扑中原始设备上的 Mysql InnoDb