LoginSignup
1
0

More than 1 year has passed since last update.

MySQL vs. TiDB-分散トランザクションの比較検証(4): MySQL内部XA(続)

Last updated at Posted at 2022-04-18
[前回] MySQL vs. TiDB-分散トランザクションの比較検証(3): MySQL内部XA

はじめに

MySQL XAの検証を続けます。
今回は、XAの注意事項と制約の観点から検証を行います。

XAトランザクションの注意事項と制約

注意1: XAトランザクションとローカル(非XA)トランザクションの関係

特定クライアント接続のコンテキスト内で、XAトランザクションとローカル(非XA)トランザクションは相互に排他的です。

  • XA STARTを使用しXAトランザクションを開始した場合、コミットまたはロールバックされるまで、ローカルトランザクションを開始できない
  • START TRANSACTIONを使用しローカルトランザクションを開始した場合、コミットまたはロールバックされるまで XAステートメントを使用できない

実際、検証してみます

検証環境と事前準備は、以下をご参照ください。
検証環境

操作用端末を二つ開きます。

  • 端末1
  • 端末2
端末1から
  • mysqlコマンドでMySQL接続し、データベース指定
$ mysql -u user -p
mysql> USE test;
  • XAトランザクションを開始
    myxaは、XAトランザクションの一意識別子
mysql> XA START 'myxa';
  • 同じセッションからローカルトランザクションを開始
mysql> START TRANSACTION;
ERROR 1399 (XAE07): XAER_RMFAIL: The command cannot be executed when global transaction is in the  ACTIVE state

案の定、ローカルトランザクションを開始できません。

  • 1行INSERT
mysql> INSERT INTO theater VALUES (4, 'NO');
  • XA END実行し、トランザクションをIDLE状態に
mysql> XA END 'myxa';
  • 再度、同じセッションからローカルトランザクションを開始
mysql> START TRANSACTION;
ERROR 1399 (XAE07): XAER_RMFAIL: The command cannot be executed when global transaction is in the  IDLE state

XAトランザクションがIDLE状態になっても、ローカルトランザクションは開始できません。

  • XA PREPARE実行し、トランザクションを準備
mysql> XA PREPARE 'myxa';
  • 再度、同じセッションからローカルトランザクションを開始
mysql> START TRANSACTION;
ERROR 1399 (XAE07): XAER_RMFAIL: The command cannot be executed when global transaction is in the  PREPARED state

XAトランザクションがPREPARED状態でも、ローカルトランザクションは開始できません。

  • XA COMMIT実行し、PREPARED状態のトランザクションをコミット
mysql> XA COMMIT 'myxa';
  • 再度、同じセッションからローカルトランザクションを開始
mysql> START TRANSACTION;
Query OK, 0 rows affected (0.00 sec)

XAトランザクションがコミットされたため、ローカルトランザクションを開始できました。

  • 1行INSERT
mysql> INSERT INTO theater VALUES (5, 'NO');

このままの状態で、端末2を開きます。

端末2から
  • mysqlコマンドでMySQL接続し、データベース指定
$ mysql -u user -p
mysql> USE test;
  • XAトランザクションを開始
    myxaは、XAトランザクションの一意識別子
mysql> XA START 'myxa';
  • 1行INSERT
mysql> INSERT INTO theater VALUES (6, 'NO');
  • XA END実行し、トランザクションをIDLE状態に
mysql> XA END 'myxa';
  • XA PREPARE実行し、トランザクションを準備
mysql> XA PREPARE 'myxa';
  • XA COMMIT実行し、PREPARED状態のトランザクションをコミット
mysql> XA COMMIT 'myxa';

端末1のセッションで、ローカルトランザクションが開始状態でも、
端末2の別セッションからは、XAトランザクションを問題なく実行できました。

注意2: XAトランザクションがACTIVE状態の場合、暗黙的にコミットが発行されるステートメントを実行できない

  • 暗黙的にコミットが発行されるステートメントにより、現在セッションでアクティブなすべてのトランザクションが暗黙的に終了される
  • XA規約に違反し、XAトランザクションをロールバックできなくなるため、以下のエラーが発生する
ERROR 1399 (XAE07): XAER_RMFAIL: The command cannot be executed
when global transaction is in the ACTIVE state
  • 注意事項に該当する、暗黙的にコミットが発行されるステートメント
    • データベースオブジェクトを定義または変更するデータ定義言語(DDL)ステートメント
    • MySQLデータベース内のテーブルを暗黙的に使用または変更するステートメント
    • トランザクション制御およびロックステートメント
    • データロードステートメント
    • 管理ステートメント
    • レプリケーション制御ステートメント

※ 引用元: https://dev.mysql.com/doc/refman/8.0/ja/implicit-commit.html

実際、検証してみます

端末を開きます
  • mysqlコマンドでMySQL接続し、データベース指定
$ mysql -u user -p
mysql> USE test;
  • XAトランザクションを開始
    myxaは、XAトランザクションの一意識別子
mysql> XA START 'myxa';
  • 1行INSERT
mysql> INSERT INTO theater VALUES (7, 'NO');

XAトランザクションがACTIVE状態の場合、
INSERT文は問題なく実行できます。

  • 暗黙的にコミットが発行されるTRUNCATE TABLEを実行
mysql> TRUNCATE TABLE theater;
ERROR 1399 (XAE07): XAER_RMFAIL: The command cannot be executed when global transaction is in the  ACTIVE state

XAトランザクションがACTIVE状態の場合、
暗黙的にコミットが発行されるステートメントは失敗します。

制約: XAトランザクションは、InnoDBストレージエンジンのみ使用可能

  • 外部XAの場合
    • MySQLサーバーがリソースマネージャーとして機能
    • クライアントプログラムがトランザクションマネージャーとして機能
  • 内部XAの場合
    • MySQLサーバー内のストレージエンジンがリソースマネージャーとして機能
    • MySQLサーバー自体がトランザクションマネージャーとして機能
    • 内部XAをサポート可能かは、個々のストレージエンジンの機能により制限される
    • 内部XAは、複数のストレージエンジンが関与するXAトランザクション処理に必要
    • 内部XAの実装で、ストレージエンジンがテーブルハンドラレベルでの2フェーズコミットをサポートしている必要があり
      • これを満たすのはInnoDBのみ

結局、今まで検証したのは内部XAでした。
- ストレージエンジンInnoDBがリソースマネージャーとして機能
- MySQLサーバーがトランザクションマネージャーとして機能

おわりに

次回から、外部XAを検証してみます。
お楽しみに。

[次回] MySQL vs. TiDB-分散トランザクションの比較検証(5): TiDBの基本
1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0