web-dev-qa-db-ja.com

mysqlのSET autocommit = 1とSTART TRANSACTIONの違い(何か見逃していませんか?)

私はMySQLのトランザクションを読んでおり、特定の何かを正しく把握しているかどうかはわかりません。それを正しく理解したことを確認したいので、ここに行きます。トランザクションが何をすべきかを知っていますが、ステートメントのセマンティクスを理解したかどうかはわかりません。

だから、私の質問は、次の点で何か間違っています(そして、その場合は何が間違っています):

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

現在、SET autocommit=0;はトランザクションを開始し、SET autocommit=1;は暗黙的にコミットします。 COMMIT;およびROLLBACK;を使用することができます。どちらの場合も、自動コミットはその後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 -分離レベルがあると見なすことは、トランザクションがあることを意味します。つまり、オートコミットはとにかくオフにする必要がありますか?

また、トランザクションの開始と自動コミットの設定との間に別の違い(上記のもの以外)がある場合、それは何ですか?

65
ralokt

データベースのトランザクション処理(自動コミット、明示的および暗黙的)に注意することで、バックアップからデータを復元する必要がなくなります。

トランザクションは、データ操作ステートメントを制御して、それらがアトミックであることを保証します。 「アトミック」とは、トランザクションが発生するか、発生しないことを意味します。トランザクションの完了をデータベースに通知する唯一の方法は、COMMITまたはROLLBACKステートメントのいずれかを使用することです(ANSI-92により、悲しいことにトランザクションを作成/開始するための構文が含まれていませんでした)ベンダー固有です)。 COMMITは、トランザクション内で行われた変更(ある場合)を適用します。 ROLLBACKは、トランザクション内で行われたアクションを無視します-UPDATE/DELETEステートメントが意図しない何かを行う場合に非常に望ましいです

通常、個々のDML(挿入、更新、削除)ステートメントは自動コミットトランザクションで実行されます-ステートメントが正常に完了するとすぐにコミットされます。これは、あなたのような場合にステートメントが実行される前の状態にデータベースをロールバックする機会がないことを意味します。問題が発生した場合、利用可能な復元オプションは、バックアップからデータを再構築することだけです(データが存在する場合)。 MySQLでは、 自動コミットはonInnoDBのデフォルト -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ステートメントの試行に対する正確性priorを確認します。

補遺

DDL(データ定義言語)ステートメントは自動的にコミットされます-COMMITステートメントは不要です。 IE:テーブル、インデックス、ストアドプロシージャ、データベース、およびビューの作成または変更ステートメント。

64
OMG Ponies

InnoDBにはSTART TRANSACTION;があり、このエンジンではSET AUTOCOMMIT = 0;(don InnoDBのトランザクションにSET AUTOCOMMIT = 0;を使用しないでください読み取り専用トランザクションの最適化に使用する場合を除きます。 COMMIT;でコミットします。

InnoDBSET AUTOCOMMIT = 0;を使用して、トランザクション用ではなく、テスト用にすることができます。

MyISAMでは、START TRANSACTION;がありません。このエンジンでは、トランザクションにSET AUTOCOMMIT = 0;を使用します。 COMMIT;またはSET AUTOCOMMIT = 1;でコミットします(以下のMyISAMの例の解説で違いを説明します)。 InnoDBでもこの方法でトランザクションを行うことができます。

ソース: http://dev.mysql.com/doc/refman/5.6/en/glossary.html#glos_autocommit

一般的な使用トランザクションの例:

/* InnoDB */
START TRANSACTION;

INSERT INTO table_name (table_field) VALUES ('foo');
INSERT INTO table_name (table_field) VALUES ('bar');

COMMIT; /* SET AUTOCOMMIT = 1 might not set AUTOCOMMIT to its previous state */

/* MyISAM */
SET AUTOCOMMIT = 0;

INSERT INTO table_name (table_field) VALUES ('foo');
INSERT INTO table_name (table_field) VALUES ('bar');

SET AUTOCOMMIT = 1; /* COMMIT statement instead would not restore AUTOCOMMIT to 1 */
18
mikl

MySQLがデフォルトでautocommitを1に設定するため、ロールバックを使用する場合は、トランザクションの開始を使用します。

2
RINSON KE