Springフレームワークによる分散トランザクション検証(Atomikos)

こんにちは。エンジニアマネージャーの岩本です。
最近はマネージメントの傍らPJの基盤技術を構築したりしています。

最近新規ゲームPJの基盤構築をしていて、MySQLの分散トランザクションについて検証をしました。
運用中のタイトルでは結構力技でDB分散をしていますが、「保守が大変」「もっとスマートに出来るようになりたい」という懸念点がありました。
せっかく新規で作れるならばこの際思い切って変えてしまえ!!という勢いです。
※運用中のタイトルのDB分散はこちらの記事を参照して下さい。

MySQLの分散トランザクション(XAトランザクション)のクエリー例が下記となります。
ローカル環境でテストをしたときのログを表示しています。DBのスキーマーを2つ用意してそれぞれにselect,insertをしたときの例です。
ログの見方は左から「ID」「コマンド」「クエリー」です。

DBログ

通常のトランザクションと違うところは「XA START」「XA END」「XA PREPARE」「XA COMMIT」です。コマンドの詳しい説明はMySQLマニュアルを参照して下さい。
今回紹介するのは、オープンソースのJTA実装であるAtomikosを使用した分散トランザクションの導入です。Javaでオープンソースな分散トランザクションのライブラリですが、ググってもAtomikos以外の情報があまり無いですね。商用版ならば何個かあったのですが・・・という状況です。良いのあったら教えて下さい!!

また、設定に関して追加したい項目の記載がなかったため、ライブラリのソースを確認しながらの作業となりました。

Atomikosマニュアル

検証環境は以下のとおりです。

– MySQL5.6
– Java:1.8
– spring : 4.1.4.RELEASE
– mybatis : 3.3.0
– mybatis-spring : 1.2.3
– mysql-connector-java : 5.1.36
– Atomikos transactions-jdbc: 3.9.3
– jta : 1.1

Spring+MyBatis+Atomikosとの連携方法

下記図1のような2つのuserDB構成のサンプルを作っていきます。「user_01DB」「user_02DB」の各DBのテーブル構成は同じです。各DBの振り分けのロジックは、「ユーザIDをDB数で割った余り」のような単純なロジックで既にアプリ側に実装されているものとします。

データベース構成図

データソース設定

    
    
        
        
        
        
        
        
        
        
            
                true
                UTF-8
                3000
                3000
                true
            
        
    

    
    
    
        
        
        
        
            
                jdbc:mysql://127.0.0.1:3306/master
                root
                
            
        
    

    
    
        
        
        
        
            
                jdbc:mysql://127.0.0.1:3306/user"
                root
                
            
        
    

今回データソースとして、Atomikosのcom.atomikos.jdbc.AtomikosDataSourceBeanを使用しています。これをdbcpとあわせて使用したい場合はorg.apache.commons.dbcp.BasicDataSourceに変えて設定も合わせて下さい。

設定のポイントとしては、DBを分散する時に「共通の設定」と「DB個別の設定」に分けている点です。これによりDBが増えたときの設定ファイルの肥大化を抑えています。

共通設定を作成するポイント

 

上記設定部分の「abstract=”true”」を追加しabstract属性にすることです。parent属性と合わせて使用するとJavaの継承パターンを実現することができます

DB毎設定を作成するポイント:


    

parent="xaDataSourceBasexaDataSourceBaseを継承しています。 props merge="true"で親のxaPropertiesの定義にDB毎の個別設定を追加しています。

これにより各DB共通の項目はxaDataSourceBaseにまとめ個別項目は「userDataSource_1」と「userDataSource_2」に分けることが出来ます。

MyBatisとの連携設定

    
    
        
        
    

    
    
        
        
    
    
        
        
    

    
    
        
        
    
    
        
        
    

同じように共通設定と個別設定をわけています。その他の設定はMyBatisのマニュアル通りです。

また実際のプロジェクトでは、Mapperの設定に関してDBが増えても設定があまり増えないようにカスタマイズをしています。

トランザクションマネージャー設定

    
    
        
            
            
                
                
            
        
        
        
            
                
                true
                
                com.atomikos.icatch.standalone.UserTransactionServiceFactory
            
        
    

    
        
        
            
                10000
                10000
                200
                false
                ./
                atomikos.log
            
        
    

    
    
    
         
         
    
   
   

トランザクションンマネージャーとして、Atomikosを使う設定です。userTransactionServiceImplは、初期化時にデフォルトでtransactions.propertiesというプロパティファイルを検索し、見つからないと警告ログを出力します。
設定ファイルを複数に分けたくないためsetAtomikosSystemPropsでプロパティファイルを検索しないように設定しています。

まとめ

マニュアル等で公開されている設定方法は、説明の都合上必要最低限の設定の場合が多い印象でした。
実際に実務で使用する場合は、プロジェクトの要件に合わせてカスタマイズする必要がありますが、その一例として参考にしていただければ幸いです。

次回は、分散トランザクションとは違うアプローチで、「SpringのChainedTransactionManager」と「LazyConnectionDataSourceProxy」を使用したトランザクションの構築について紹介出来ればと思っています。