重複キーエラーはmysqlトランザクションをキャンセル/ロールバックしません
-
06-07-2019 - |
質問
mysql innodbトランザクションで、重複キーエラーが発生してロールバックが発生することが予想されます。そうではなく、単にエラーをスローして次のコマンドに進みます。 COMMITコマンドに到達すると、重複キーによりコマンドが発生することなく、トランザクションがコミットされます。
これは予想される動作ですか?もしそうなら、そのようなエラーが発生したときにトランザクションをコミットするのではなくロールバックするように設定するにはどうすればよいですか?
テスト環境:
CREATE TABLE `test` (
`id` int(11) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
BEGIN;
INSERT INTO test VALUES (5);
INSERT INTO test VALUES (5);
COMMIT;
期待される結果:テーブル test
は空です
実際の結果:テーブル test
には値5の1つのレコードが含まれています
解決
MySql(および他のSQLエンジン)は、エラーが発生した場合、トランザクションを自動的にロールバックしません。
トランザクションをロールバックするエラーハンドラを宣言する必要があります。
DECLARE EXIT HANDLER FOR SQLEXCEPTION, SQLWARNING, NOT FOUND
BEGIN
ROLLBACK;
CALL ERROR_ROLLBACK_OCCURRED;
END;
他のヒント
重複が原因で挿入が失敗した場合、データベースはトランザクションをそのステートメントの先頭にロールバックします。
ステートメントの最初に作成された内部セーブポイントを使用し、そのセーブポイントにロールバックします。
トランザクション全体がロールバックされるわけではありません。それが望んでいたものではなかった可能性があるためです。
mysqlクライアントの動作は、コマンドラインパラメーターを使用して構成できます。終了(暗黙的にロールバック)または続行できます。
独自のアプリを使用している場合、それはユーザー次第です。
Mysqlは、障害の処理方法にポリシーを課しません。アプリケーションにそれを任せます。したがって、それらについてあなたがすることはあなた自身のビジネスです-あなたが好きならそれらを無視することができます。