XA トランザクション

1. XA トランザクション SQL 構文
2. XA トランザクションの状態

InnoDB ストレージ エンジンでは、XA トランザクションがサポートされています。MySQL XA インプリメンテーションは X/Open CAE ドキュメント Distributed Transaction Processing:XA 仕様 に基づいています。この文書はオープン グループによって出版されていて、http://www.opengroup.org/public/pubs/catalog/c193.htm で入手可能です。現在の XA インプリメンテーションの制限については、 項D.5. 「XA トランザクションの規制」 で説明されています。

クライアント側には、特別な事は何も要求されません。MySQL サーバへの XA インターフェースは、XA キーワードで始まる SQL ステートメントで構成されています。MySQL クライアント プログラムは、SQL ステートメントを送り、XA ステートメント インターフェースの動作を理解する事が可能である必要があります。それらは最近のクライアント ライブラリに違反してリンクされる必要はありません。古いクライアント ライブラリもまた機能します。

現在、MySQL コネクタの中では、MySQL コネクタ/J 5.0.0 が XA ディレクトリをサポートします。 (XA SQL ステートメント インターフェースを扱うクラス インターフェースを利用して)

XA は分散型のトランザクションをサポートします。それは、複数の別々のトランザクション リソースを、グローバル トランザクションに参加させる事ができる能力です。トランザクション リソースは RDBMS である事が多いのですが、別の種類である可能性もあります。

グローバル トランザクションは、それら自身の中でトランザクションのアクションをいくつか含んでいますが、それらは全て、グループとして成功するか、グループとしてロールバックされる必要があります。要するに、これは複数の ACID トランザクションが、ACID 特性を持つグローバル操作のコンポーネントとして一斉に実行されるように ACID 特性を 「1レベル上げる」 という事です。(しかし、分散型のトランザクションには、ACID 特性を達成する為に、SERIALIZABLE 分離レベルを利用しなければいけません。非分散型のトランザクションには REPEATABLE READ の利用で十分ですが、分散型のトランザクションに対しては十分では有りません。)

分散型トランザクションのいくつかの例

グローバル トランザクションを利用するアプリケーションは、1つ、または複数のリソース マネージャと、1つのトランザクション マネージャを含んでいます。

XA MySQL の MySQL インプリメンテーションは、MySQL サーバがグローバル トランザクション内で XA トランザクションを扱うリソース マネージャとして機能する事を可能にします。MySQL サーバに接続するクライアントプログラムは、トランザクション マネージャとして機能します。

グローバル トランザクションを実行するには、どのコンポネントが関係しているかを知り、それらをそれぞれ、コミットまたはロールバックできる時にポイントまで持ってくる事が必要です。 各コンポネントがそれぞれの能力についてどのようなレポートをするかによって、それらは全て1つのアトミック グループとしてコミット、またはロールバックしなければいけません。 それは、全てのコンポネントがコミットするか、または全てのコンポネントがロールバックするという事です。グローバル トランザクションを管理するには、コンポネントか、接続ネットワークが失敗する可能性があるという事を考慮に入れておく事が必要です。

グローバル トランザクションを実行するプロセスは、二相コミットを利用します。(2PC)これは、グローバル トランザクションのブランチによって行われるアクションが実行された後に起こります。

  1. 第一段階で、全てのブランチが準備されます。それは、TM からコミットの準備の命令が出るという事です。通常、これはブランチが管理する各 RM が、安定したストレージの中にブランチの為のアクションを記録するという事を意味します。ブランチは、それらが利用可能かどうかを指示し、その結果は第二段階に利用されます。

  2. 第二段階では、TM が RM にロールバックを行うかどうかの指示を出します。もし全てのブランチの準備が整った時それらがコミットが可能だという連絡を出せは、それら全てにコミットの指示が出されます。もしブランチの準備が整った時にどれか1つでもコミットが不可能であるという連絡があれば、全てのブランチにロールバックの指示が出されます。

場合によっては、グローバル トランザクションは単相コミットを利用します。(1PC)例えば、トランザクション マネージャがたった1つのトランザクション リソースで成り立っているグローバル トランザクションを見つけたら(それを単一ブランチといいます)、そのリソースには準備とコミットを同時にするように指示が出されます。

1. XA トランザクション SQL 構文

MySQL 内で XA トランザクションを行うには、次のステートメントを利用してください。

XA {START|BEGIN} xid [JOIN|RESUME]

XA END xid [SUSPEND [FOR MIGRATE]]

XA PREPARE xid

XA COMMIT xid [ONE PHASE]

XA ROLLBACK xid

XA RECOVER

XA START に対しては、JOINRESUME 条項はサポートされていません。

XA END に対しては、SUSPEND [FOR MIGRATE] 条項はサポートされていません。

各 XA ステートメントは XA キーワードで始まり、それらのほとんどが xid 値を必要とします。xid は XA トランザクション識別子です。それは、ステートメントがどのトランザクションに適応するのか指示します。 xid 値はクライアントから提供されるか、MySQL サーバから発生します。xid 値は1つから3つの部分を持っています。

xid: gtrid [, bqual [, formatID ]]

gtrid はグローバル トランザクション識別子、bqual はブランチ修飾子、そして formatIDgtridbqual 値によって利用されるフォーマットを識別する数値です。構文によって指示されているように、bqualformatID は任意です。デフォルトの bqual 値は、指示されていない限り '' です。デフォルトの formatID 値は、指示されていない限り1です。

gtridbqual は文字列直定数である必要があり、それぞれが最長64バイトです(文字数ではない)。gtridbqual の指定方法は、いくつかあります。引用された文字列('ab')、16進数列 (0x6162X'ab')、またはビット値(b'nnnn')を利用する事ができます。

formatID は符号無しの整数です。

gtridbqual 値は、MySQL サーバに内在する XA サポート ルーチンによって、バイトで解釈されます。 しかし、XA ステートメントを含む SQL ステートメントが解析されると、サーバはいくつかの特定の文字セットと共に機能します。安全の為に、 gtridbqual を16進数列として書いてください。

xid 値は一般的にトランザクション マネージャによって生成されます。ある TM によって生成された値は、別の TM によって生成された値とは異なります。規定の TM は XA RECOVER ステートメントによって返された値のリスト内にある、それ自身の xid 値を識別できなければいけません。

XA START xid は、規定の xid 値を利用して XA トランザクションをスタートします。各 XA トランザクションは固有の xid 値を持つ必要があるので、その値は同時に XA トランザクションによって利用されてはいけません。一意性は gtridbqual 値を利用して評価されます。XA トランザクションに続く全ての XA ステートメントは、XA START ステートメント内で規定されているように、同じ xid 値を利用して指定されなければいけません。もし、それらのステートメントのどれかを利用しながら、既存 XA トランザクションに対応しない xid 値を指定すると、エラーが起こります。

ひとつ、または複数の XA トランザクションは同じグローバル トランザクションの一部になる事ができます。規定のグローバル トランザクション内の全ての XA トランザクションは、xid 値内で同じ gtrid 値を利用しなければいけません。この理由により、規定の XA トランザクションがどのグローバル トランザクションの一部であるかをはっきりさせる為に、gtrid 値はグローバルに一意である必要があります。xid 値の bqual 部は、グローバル トランザクションの中で、各 XA トランザクションに対して異なっている必要があります。(bqual 値が異なっている必要があるという要求は、現在の MySQL XA インプリメンテーションの制限です。これは XA 仕様の一部ではありません。)

XA RECOVER ステートメントは、PREPARED 状態にある MySQL サーバ上の XA トランザクションに情報を返します。(詳しくは 項2. 「XA トランザクションの状態」 をご確認ください。)アウトプットは、どのクライアントがスタートしたかに関わらず、サーバ上の XA トランザクションなどの行を含みます。

XA RECOVER アウトプット行はこのような形になります。('abc''def'、そして 7 部分で成り立っている xid 値の例):

mysql> XA RECOVER;
+----------+--------------+--------------+--------+
| formatID | gtrid_length | bqual_length | data   |
+----------+--------------+--------------+--------+
|        7 |            3 |            3 | abcdef |
+----------+--------------+--------------+--------+

アウトプット カラムは次の意味を持っています。

  • formatID はトランザクション xidformatID 部です。

  • gtrid_lengthxidgtrid 部の、バイトでの長さです。

  • bqual_lengthxidbqual 部の、バイトでの長さです。

  • dataxidgtridbqual 部の連結です。

2. XA トランザクションの状態

次の状態での XA トランザクションの進歩

  1. XA トランザクションをスタートさせる為に XA START を利用し、それを ACTIVE な状態にして下さい。

  2. ACTIVE XA トランザクションには、トランザクションを形成する SQL ステートメントを発行し、それから XA END ステートメントを発行してください。XA END はトランザクションを IDLE の状態にします。

  3. IDLE XA トランザクションには、XA PREPARE ステートメントか XA COMMIT ... ONE PHASE ステートメントのどちらかを発行できます。ONE PHASE ステートメント:

    • XA PREPARE はトランザクションを

      PREPARED の状態にします。

    • この時点の XA RECOVER ステートメントは、XA RECOVERPREPARED な状態にある全ての XA トランザクションをリストにする為、そのアウトプットの中にトランザクションの xid 値を含みます。

    • XA COMMIT ... ONE PHASE はトランザクションを準備し、コミットします。xid 値は、トランザクションが終了する為 XA RECOVER によってリストされません。

  4. PREPARED XA トランザクションに対して、トランザクションをコミットし、終了させる為に XA COMMIT ステートメントを発行するか、またはトランザクションをロールバックして終了させる為に XA ROLLBACK を発行できます。

ここに、行をテーブルにグローバル トランザクションの一部として挿入するシンプルな XA トランザクションの例があります。

mysql> XA START 'xatest';
Query OK, 0 rows affected (0.00 sec)

mysql> INSERT INTO mytable (i) VALUES(10);
Query OK, 1 row affected (0.04 sec)

mysql> XA END 'xatest';
Query OK, 0 rows affected (0.00 sec)

mysql> XA PREPARE 'xatest';
Query OK, 0 rows affected (0.00 sec)

mysql> XA COMMIT 'xatest';
Query OK, 0 rows affected (0.00 sec)

既存のクライアント接続のコンテキストの中で、XA トランザクションとローカル トランザクション(非 XA)は、お互いに 排他的です。例えば、もし XA トランザクションを始める為に XA START が発行されたら、XA トランザクションがコミットされるかロールバックされるまで、ローカル トランザクションはスタートできません。逆に、もしローカル トランザクションが START TRANSACTION でスタートされたら、トランザクションがコミットされるかロールバックされるまで、XA トランザクションは利用できません。

もしXA トランザクションが ACTIVE な状態であれば、暗黙的なコミットを引き起こすステートメントの発行はできないという事に注意してください。XA トランザクションをロールバックする事はできないので、これはXA 規約に違反するという事になります。もしこのようなステートメントを実行しようとすると、次のようなエラーが発生します。

ERROR 1399 (XAE07): XAER_RMFAIL: The command cannot be executed
when global transaction is in the ACTIVE state

ステートメントが上記のどの注意事項に当てはまるのかは、項 「暗黙のコミットを引き起こすステートメント」 でリストアップされています。