2

エラーが発生した場合(重複キーなど)にトランザクションとロールバックを使用することを楽しみにしています。

自動コミットを無効にしてエラーが発生した場合、トランザクションはコミットされるべきでなくてもコミットされています。

これが私のコードの一部です:

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

ご協力いただきありがとうございます。

4

2 に答える 2

1

アプリケーションでは、次のように記述します-

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 ハンドラを使用できないため、ストアド プロシージャからこのコードを実行します。

于 2012-05-15T16:26:53.383 に答える
1

このリンクを参照してください

ステートメントで IGNORE オプションを指定していない場合、重複キー エラーにより SQL ステートメントがロールバックされます。

于 2015-10-02T23:51:33.460 に答える