Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/67.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
MySQL在重复密钥上回滚_Mysql_Transactions_Innodb_Commit_Rollback - Fatal编程技术网

MySQL在重复密钥上回滚

MySQL在重复密钥上回滚,mysql,transactions,innodb,commit,rollback,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, PR

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

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

这是我的代码:

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子句。我可以这样建议你,并附上一份声明-

  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中,无法在脚本中使用声明处理程序。

请参阅

如果未在语句中指定IGNORE选项,则重复键错误会回滚SQL语句


运行此操作之前是否要删除表?请确保这些表实际上是InnoDB-如果您将它们创建为InnoDB,但服务器上未安装InnoDB,则它们将创建为MyISAM表