web-dev-qa-db-ja.com

COMMIT TRANSACTIONに到達しない場合の自動ロールバック

以下を検討してください:

START TRANSACTION;

BEGIN;

INSERT INTO prp_property1 (module_name,environment_name,NAME,VALUE) VALUES ('','production','','300000');

/** Assume there is syntax error SQL here...**/
Blah blah blah

DELETE FROM prp_property1 WHERE environment_name = 'production';

COMMIT TRANSACTION;

質問:

トランザクションが自動的にロールバックされ、レコード挿入の試行が失敗することに気付きました。

上記のようにROLLBACK TRANSACTIONと共にエラーハンドラーまたはエラーチェックを提供しない場合、COMMIT TRANSACTIONは実行されないため、上記の例のように機能しているように見えるので安全ですか?

トランザクションはすぐにロールバックされ、エラーが発生するとすぐに破棄されると思います。

17
Koekiebox

いいえ、エラーが発生してもトランザクションはロールバックされません。ただし、このポリシーを適用するクライアントアプリケーションを使用している可能性があります。

たとえば、mysqlコマンドラインクライアントを使用している場合、通常、エラーが発生すると実行が停止し、終了します。トランザクションの進行中に終了すると、トランザクションはロールバックされます。

独自のアプリケーションを作成している場合、ロールバックのポリシーを制御できますが、いくつかの例外があります。

  • 終了(つまり、データベースから切断)すると、常に進行中のトランザクションがロールバックされます。
  • デッドロックまたはロック待機タイムアウトにより、暗黙的にロールバックが発生します

これらの条件以外では、エラーを生成するコマンドを呼び出すと、エラーは通常どおり返され、トランザクションのコミットなど、好きなことを自由に実行できます。

26
MarkR

procedureを使用して、これをより効果的に行うことができます。
MySQLサーバーのストアドプロシージャを使用したトランザクション

8
tech_me

Mysqlストアドプロシージャを使用する

   BEGIN

   DECLARE exit handler for sqlexception
      BEGIN
      ROLLBACK;
   END;

   DECLARE exit handler for sqlwarning
     BEGIN
     ROLLBACK;
   END;

   START TRANSACTION;

   INSERT INTO prp_property1 (module_name,environment_name,NAME,VALUE) VALUES ('','production','','300000');

   [ERROR]

   COMMIT;

   END

警告またはエラーのロールバックを設定すると、トランザクションはすべてのエントリが削除されるため、削除する必要はありません。

8

@MarkRがすでに言ったことに追加したいと思います。 InnoDBエンジンを想定したエラー処理は、 Mysqlサーバーのドキュメント の説明に従って行われます。

  • テーブルスペースのファイルスペースが不足すると、MySQLテーブルがいっぱいのエラーが発生し、InnoDBがSQLステートメントをロールバックします。
  • トランザクションのデッドロックにより、InnoDBはトランザクション全体をロールバックします。
  • 重複キーエラーはSQLステートメントをロールバックします
  • 行が長すぎるエラーは、SQLステートメントをロールバックします。
  • その他のエラーは主にコードのMySQLレイヤー(InnoDBストレージエンジンレベルより上)で検出され、対応するSQLステートメントをロールバックします。

Mysqlセッションが終了すると(phpスクリプトが終了すると)、コミットされていないものはすべてロールバックされることも理解しています。私はまだこの声明を裏付けるために本当に信頼できる情報源を見つける必要があるので、私の言葉をそれに取ってはいけません。

5
Nicola Pedretti

私はこれら3つの状況をテストしました。 mySQLは自動的にロールバックしません。

トランザクションのデッドロックにより、InnoDBはトランザクション全体をロールバックします。重複キーエラーがSQLステートメントをロールバックする長すぎる行エラーがSQLステートメントをロールバックします。

影響を受けるレコードだけが失敗し、アプリケーションが明示的に「ロールバック」を呼び出さない限り、残りのレコードは成功します。

0
Wen