以下を検討してください:
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
は実行されないため、上記の例のように機能しているように見えるので安全ですか?
トランザクションはすぐにロールバックされ、エラーが発生するとすぐに破棄されると思います。
いいえ、エラーが発生してもトランザクションはロールバックされません。ただし、このポリシーを適用するクライアントアプリケーションを使用している可能性があります。
たとえば、mysqlコマンドラインクライアントを使用している場合、通常、エラーが発生すると実行が停止し、終了します。トランザクションの進行中に終了すると、トランザクションはロールバックされます。
独自のアプリケーションを作成している場合、ロールバックのポリシーを制御できますが、いくつかの例外があります。
これらの条件以外では、エラーを生成するコマンドを呼び出すと、エラーは通常どおり返され、トランザクションのコミットなど、好きなことを自由に実行できます。
procedureを使用して、これをより効果的に行うことができます。
MySQLサーバーのストアドプロシージャを使用したトランザクション
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
警告またはエラーのロールバックを設定すると、トランザクションはすべてのエントリが削除されるため、削除する必要はありません。
@MarkRがすでに言ったことに追加したいと思います。 InnoDBエンジンを想定したエラー処理は、 Mysqlサーバーのドキュメント の説明に従って行われます。
- テーブルスペースのファイルスペースが不足すると、MySQLテーブルがいっぱいのエラーが発生し、InnoDBがSQLステートメントをロールバックします。
- トランザクションのデッドロックにより、InnoDBはトランザクション全体をロールバックします。
- 重複キーエラーはSQLステートメントをロールバックします
- 行が長すぎるエラーは、SQLステートメントをロールバックします。
- その他のエラーは主にコードのMySQLレイヤー(InnoDBストレージエンジンレベルより上)で検出され、対応するSQLステートメントをロールバックします。
Mysqlセッションが終了すると(phpスクリプトが終了すると)、コミットされていないものはすべてロールバックされることも理解しています。私はまだこの声明を裏付けるために本当に信頼できる情報源を見つける必要があるので、私の言葉をそれに取ってはいけません。
私はこれら3つの状況をテストしました。 mySQLは自動的にロールバックしません。
トランザクションのデッドロックにより、InnoDBはトランザクション全体をロールバックします。重複キーエラーがSQLステートメントをロールバックする長すぎる行エラーがSQLステートメントをロールバックします。
影響を受けるレコードだけが失敗し、アプリケーションが明示的に「ロールバック」を呼び出さない限り、残りのレコードは成功します。