START TRANSACTION [WITH CONSISTENT SNAPSHOT] | BEGIN [WORK] COMMIT [WORK] [AND [NO] CHAIN] [[NO] RELEASE] ROLLBACK [WORK] [AND [NO] CHAIN] [[NO] RELEASE] SET autocommit = {0 | 1}
START
TRANSACTION
または
BEGIN
ステートメントは、新しいトランザクションを開始します。COMMIT
は、その変更を恒久的なものにし、現在のトランザクションを行います。ROLLBACK
はその変更をキャンセルし、現在のトランザクションをロールバックします。SET
autocommit
ステートメントは、現在のセッションに対するデフォルトの自動コミットモードを無効または有効にします。
任意の WORK
キーワードは、CHAIN
と
RELEASE
節のように COMMIT
と
ROLLBACK
に対してサポートされています。CHAIN
と RELEASE
はトランザクション完了に対する追加コントロールに利用されます。completion_type
システム変数の値はデフォルトの完了動作を決定します。Server System Variables
を参照してください。
すべてのストアドプログラム
(ストアドプロシージャーとストアドファンクション、トリガー、およびイベント)
内で、パーサーは、BEGIN
[WORK]
を
BEGIN
... END
ブロックの開始として扱います。このコンテキストでは、代わりに
START
TRANSACTION
を使用してトランザクションを開始します。
AND CHAIN
節は、現在のトランザクションが終わったらすぐに新しいトランザクションが始まるよう働きかけ、その新しいトランザクションは終わったばかりのトランザクションと同じ遮断レベルを持ちます。RELEASE
節を指定すると、サーバーは、現在のトランザクションを終了したあと現在のクライアントセッションを切り離します。NO
キーワードを含むことは、もし
completion_type
システム変数がデフォルトで変更やリリース完了を引き起こすよう設定されれば有効となる、CHAIN
や RELEASE
完了を食い止めます。
デフォルトにより、MySQL は自動コミットモードが有効な状態で起動します。つまり、テーブルを更新 (変更) するステートメントを実行するとすぐに、MySQL によってその更新がディスクに格納されて永続的になります。自動コミットモードを無効にするには、次のステートメントを使用します。
SET autocommit=0;
autocommit
変数を 0
に設定することによって自動コミットモードを無効にしたあと、トランザクションセーフテーブル
(InnoDB
または
NDBCLUSTER
のテーブルなど)
への変更が、ただちに永続的になるわけではありません。変更をディスクに格納するには
COMMIT
を、変更を無視するには
ROLLBACK
を使用する必要があります。
一連のステートメントに対して自動コミットモードを無効にするためには、START
TRANSACTION
ステートメントを利用してください。
START TRANSACTION; SELECT @A:=SUM(salary) FROM table1 WHERE type=1; UPDATE table2 SET summary=@A WHERE type=1; COMMIT;
START
TRANSACTION
を利用すると、自動コミットは
COMMIT
や
ROLLBACK
を利用してトランザクションを終了するまで無効のままです。そして自動コミットモードはその前の状態に戻ります。
BEGIN
と
BEGIN
WORK
は、トランザクションを始める
START
TRANSACTION
のエイリアスとしてサポートされています。START
TRANSACTION
はスタンダード SQL
構文で、アドホックトランザクションを始める方法として推奨されています。
MySQL
クライアントアプリケーションを記述するために使用される多くの
API (JDBC など) は、クライアントから
START
TRANSACTION
ステートメントを送信する代わりに使用できる
(また、場合によっては使用する必要のある)、トランザクションを開始するための独自のメソッドを提供しています。更なる情報については、Connectors and APIs
か、ご利用の API
の説明書を参照してください。
BEGIN
ステートメントは、BEGIN ...
END
複合ステートメントを開始する
BEGIN
キーワードの利用とは異なります。後者はトランザクションを開始しません。項8.8.1. 「BEGIN ... END
複合ステートメント構文」
を参照してください。
このようにトランザクションを開始することもできます。
START TRANSACTION WITH CONSISTENT SNAPSHOT;
WITH CONSISTENT SNAPSHOT
節は、一貫性のある読み取りが可能であるストレージエンジンに対して、それを開始します。これは、InnoDB
にのみ適用されます。その効果は、InnoDB
テーブルから
SELECT
が後に続く START
TRANSACTION
を発行することと同じです。詳しくは項9.8.2. 「一貫性非ロック読み取り」を参照してください。WITH
CONSISTENT SNAPSHOT
節は現在のトランザクションの遮断レベルを変更しないので、現在の遮断レベルが一貫性のある読み取りを許容するものである場合のみ
(REPEATABLE
READ
か
SERIALIZABLE
)、一貫性のあるスナップショットを提供します。
トランザクションを開始すると、未解決のトランザクションを引き起こします。詳細については、項8.4.3. 「暗黙のコミットを引き起こすステートメント」 を参照してください。
トランザクションを開始すると、LOCK
TABLES
を利用して行ったテーブルロックを、まるで
UNLOCK
TABLES
を実行したかのように解除してしまいます。トランザクションを開始しても、FLUSH
TABLES WITH READ LOCK
を利用して行われたグローバル読み取りロックの解除はしません。
最適な結果を得るために、トランザクションは、1 つのトランザクションセーフストレージエンジンによって管理されているテーブルのみを使用して実行するようにしてください。そうでなければ、次のような問題が起きます。
もし複数のトランザクションセーフストレージエンジンのテーブルを利用していて
(InnoDB
や
Falcon
のような)、またトランザクションの遮断レベルが
SERIALIZABLE
でないならば、1
つのトランザクションが行われたときに同じテーブルを利用する別の実行中のトランザクションが、最初のトランザクションによって行われた変更だけを見るということが可能です。これは、トランザクションのアトミック性が、混合エンジンに保障されておらず、矛盾した結果になり得るということです。(もし混合エンジントランザクションが頻繁でなければ、必要に応じて遮断レベルを
SERIALIZABLE
に設定するために、1
つのトランザクション単位で
SET TRANSACTION
ISOLATION LEVEL
を利用することができます)。
トランザクション内でトランザクションセーフでないテーブルを使用する場合は、自動コミットモードのステータスには関係なく、それらのテーブルへの変更が一度に格納されます。
トランザクション内で非トランザクションテーブルを更新したあとに
ROLLBACK
ステートメントを発行すると、ER_WARNING_NOT_COMPLETE_ROLLBACK
警告が発生します。トランザクションセーフテーブルへの変更はロールバックされますが、非トランザクションセーフテーブルへの変更はロールバックされません。
各トランザクションは
COMMIT
によって、1
つの塊でバイナリログの中に格納されています。ロールバックされたトランザクションはログされません。(例外:
非トランザクションテーブルへの変更はロールバックできません。ロールバックされるトランザクションに非トランザクションテーブルへの変更が含まれている場合は、非トランザクションテーブルへの変更が確実に複製されるようにするために、最後に
ROLLBACK
ステートメントを使用してトランザクション全体がログに記録されます。)
The Binary Log を参照してください。
SET
TRANSACTION ISOLATION LEVEL
を利用してトランザクションの遮断レベルを変更することができます。項8.4.6. 「SET TRANSACTION
構文」
を参照してください。
ロールバックは、ユーザーが明示的に求めることなく
(たとえば、エラーの発生時に)
暗黙的に発生する可能性のある低速な操作になる場合があります。このため、ROLLBACK
ステートメントを使用して実行された明示的なロールバックに対してだけでなく、暗黙のロールバックに対しても、SHOW
PROCESSLIST
はセッションの
State
カラムに
Rolling back
を表示します。
MySQL 5.1.36
からは、BEGIN
、COMMIT
、および
ROLLBACK
は
--replicate-do-db
または
--replicate-ignore-db
規則の影響を受けなくなりました。(Bug#43263)