1. ホーム
  2. mysql

[解決済み] SET autocommit=1 と START TRANSACTION の違い (何か見落としがある?)

2023-02-28 20:52:18

質問

MySQL のトランザクションについて読んでいるのですが、具体的に何かを正しく把握できているのかどうか、また、自分が正しく理解しているのかどうかを確認したいので、以下に説明します。トランザクションが何をすることになっているかは知っていますが、ステートメントのセマンティクスを理解したかどうかがわからないだけです。

それで、私の質問は、何か間違っているのか、(そして、もしそうなら、何が間違っているのか)次のようなことです。

デフォルトでは、MySQL で自動コミットモードが有効になっています。

今すぐ SET autocommit=0; はトランザクションを開始します。 SET autocommit=1; は暗黙のうちにコミットします。これは COMMIT; と同様に ROLLBACK; を加えたもので、どちらの場合もその後 autocommit は 0 に設定されたままです(そして新しいトランザクションが暗黙のうちに開始されます)。

START TRANSACTION; は基本的に SET autocommit=0; になるまで COMMIT; または ROLLBACK; が行われます。

言い換えれば START TRANSACTION;SET autocommit=0; は等価であり、ただし START TRANSACTION; は暗黙のうちに SET autocommit=0; の後に COMMIT; または ROLLBACK;

ということであれば、理解できないのは http://dev.mysql.com/doc/refman/5.5/en/set-transaction.html#isolevel_serializable - を見ると、分離レベルを持つことはトランザクションが存在することを意味し、つまり、自動コミットはいずれにせよオフであるべきだということでしょうか?

トランザクションを開始することと自動コミットを設定することの間に(上記の違い以外に)別の違いがあるとすれば、それは何でしょうか?

どのように解決するのですか?

データベースのトランザクション (自動コミット、明示的および暗黙的) 処理を認識しておくと、バックアップからデータを復元する手間を省くことができます。

トランザクションは、データ操作のステートメントがアトミックであることを保証するために制御します。アトミックであるということは、トランザクションが発生するか、しないかのどちらかであることを意味します。 トランザクションの完了をデータベースに通知する唯一の方法は COMMIT または ROLLBACK ステートメント (ANSI-92 によるもので、残念ながらトランザクションを作成/開始するための構文は含まれていないため、ベンダーに依存します) を使用します。 COMMIT は、トランザクション内で行われた変更を (もしあれば) 適用します。 ROLLBACK トランザクション内で行われたどんなアクションも無視します。 .

通常、個々の DML (挿入、更新、削除) ステートメントは、自動コミット トランザクションで実行されます - ステートメントが正常に完了すると、すぐにコミットされます。 つまり、あなたのようなケースでは、ステートメントが実行される前の状態にデータベースをロールバックする機会がないことを意味します。何か問題が発生した場合、利用可能な唯一の復元オプションは、バックアップからデータを再構築することです(バックアップが存在する場合)。 MySQL では 自動コミットは にあります。 は、InnoDB のデフォルトで - MyISAMはトランザクションをサポートしていません。使用することで無効にすることができます。

SET autocommit = 0

明示的なトランザクションとは、ステートメントが明示的に定義されたトランザクションコードブロックの中にラップされている場合です。 MySQL の場合、これは START TRANSACTION . また、明示的に作られた COMMIT または ROLLBACK ステートメントをトランザクションの最後に追加します。 ネストされたトランザクションについては、このトピックの範囲外です。

暗黙的トランザクションは明示的トランザクションと若干異なります。 暗黙的なトランザクションは、トランザクションを明示的に定義する必要はありません。 しかし、明示的なトランザクションと同様に COMMIT または ROLLBACK ステートメントを提供する必要があります。

結論

明示的なトランザクションは最も理想的な解決策です - ステートメントを必要とします。 COMMIT または ROLLBACK でトランザクションを終了させ、何が起こっているのかを他の人が読めるように明確に記述します。 データベースを対話的に操作する場合は、暗黙的なトランザクションでも構いませんが COMMIT ステートメントは、結果が有効であると徹底的に判断された場合にのみ指定されるべきです。

を使うべきということです。

SET autocommit = 0;

START TRANSACTION;
  UPDATE ...;

...そして COMMIT; を使うようにしてください。

とはいえ、UPDATE と DELETE ステートメントは通常、影響を受けた行の数だけを返し、特定の詳細を返しません。 そのようなステートメントを SELECT ステートメントに変換し、結果が正しいことを確認するためにレビューします。 前に で、UPDATE/DELETE ステートメントを試行します。

補遺

DDL (Data Definition Language) ステートメントは自動的にコミットされます - COMMIT ステートメントを必要としません。 IE: テーブル、インデックス、ストアドプロシージャ、データベース、およびビューの作成または変更ステートメント。