MySQLのAUTOCOMMIT(オートコミット)覚え書き
MySQLの機能のひとつ、AUTOCOMMIT(オートコミット)が有効/無効でどのように
挙動が変わるのか、今イチ理解できていない。やっぱり、一回書いておかないと。
前提として、トランザクションセーフであるInnoDBテーブルが対象であること。
(MySAMはトランザクションをサポートしていない)
なお、この記事内における「暗黙のうちに、暗黙的」という表現は「自動的に」と同義語と
捉えるものとする。(・・・と勝手に決めます)
AUTOCOMMIT(オートコミット)有効/無効の違い
AUTOCOMMIT(オートコミット)を有効にするか無効にするかにより、トランザクション
の開始/終了の方法が変化する。
オートコミットを有効にした場合(デフォルトで有効)
この場合のトランザクションは単一のSQL文実行時に暗黙のうちに、
またはSTART TRANSACTION文によって明示的に開始される。
この中でSTART TRANSACTION文を実行したか、しなかったかによっても挙動が
変わるのでややこしい。概ね、以下のような違いがある。
1.START TRANSACTION文を実行した場合
単一のSQL文が実行されただけではコミットせず、COMMIT文を
実行した時点で初めてコミットされる。
ROLLBACK文を実行すればロールバックする。
2.START TRANSACTION文を実行しなかった場合
単一のSQL文が実行された時点で自動的にコミットする。
ロールバックはできない。
2.の場合、常に直ちにコミットされるMyISAMテーブルにおける動作と同様となる。
オートコミットを無効にした場合
この場合のトランザクションは、SQL文の実行によって暗黙的に開始する。
または、START TRANSACTION文の実行により明示的に開始する。
どちらにしても、自動的にはコミットせず、COMMIT文を実行した時点で初めて
コミットされる。また、ROLLBACK文を実行すればロールバックする。
「トランザクションはSQL文の実行によって暗黙的に開始する」が何を意味するかというと、
START TRANSACTION文の実行を忘れてしまっても自動的にトランザクションが開始される、
ということになる。
オートコミットを無効にするとユーザが常にトランザクションを
開いているとみなされる。よってユーザが明示的にCOMMIT(またはROLLBACK)
することにより現在のトランザクションが終了し、その後で新しいトランザクション
が開始される、という挙動になるわけだ。
AUTOCOMMITの値の確認や変更
InnoDBではデフォルトでオートコミットが有効になっているため、明示的に
START TRANSACTION文を実行しない限り、INSERT文等更新系のSQL文を
実行すると自動的にコミットされ、ロールバックできない。
接続中のセッションでAUTOCOMMITの値を確認するには、以下を実行すればよい。
mysql>SELECT @@autocommit;
オートコミット機能は、SET AUTOCOMMIT文によってセッション単位で制御可能。
無効にしたい場合は以下のようにする。
mysql> SET AUTOCOMMIT=0;
AUTOCOMMITは現時点ではSET GLOBAL文やmy.cnfでグローバルに設定できないため、
デフォルト値を0にするにはひと手間必要となる。
my.cnfにて以下のように接続時の動作として設定すれば、事実上デフォルト値を0に
することができる。
[mysqld]
init_connect=’SET AUTOCOMMIT=0′
ただし、init_connectで指定したSQL文はSUPER権限を持ったユーザに対しては
実行されないことに注意。
その他、関連メモ
AUTOCOMMITが無効の場合に、最後のトランザクションを明示的にコミットせずに接続を切断
したり、MySQLインスタンスを停止した場合、実行中のトランザクションはロールバックされる。
トランザクションの開始には、START TRANSACTION文の代わりに
BEGIN文を使用してもよい。今回はこの違いについては深追いしないでおく。
AUTOCOMMIT=0の場合の注意点。
暗黙のコミットが発生する(言い換えると暗黙のうちにトランザクションが終了する)
SQL文や、ロールバックできないSQL文が存在すること。
と、以下に書いてあるのだが、、、正直意味が分からない。
MySQL4.1/9.MySQLの実験/4.トランザクション
ひょっとしてこれのこと?
13.5.10.9. 暗黙的なトランザクション コミットとロールバック
が、これも見てもよくわからないので今回は深追いしないでおく。。
ロールバックについて。
ロールバックは現在のトランザクションによって行われた全ての変更をキャンセルする、
つまり対象のトランザクション全体を無効にする。
InnoDBには、これとは別にSQL文単位でのロールバックも存在する。
Oracleにも上記と同様の機能がある。
なお、Oracleではオートコミット機能は無効になっている。
またしても深みに、、、