XAテスト移植
JBoss+MySQL用のシンプルなインテグレーションテストは既に以前作成してあったのだけれども,今回WebLogic+MySQL用に作ったものの方がよりシンプルかつテスト範囲が広いため,WebLogic用に作ったテストコードをJBoss用に移植した.
移植といってもよくみたらJNDIプロパティとデータソース名を変えるだけ(しかも定数クラスに切り出してあるので・・・)で至極簡単だったわけだが.
XDoclet用のタグもCMPとかを結局使わないことになったので"@ejb"から始まるやつのみ.
ところで,WebLogicは最後まで悩ませてくれる.以下のコードをEJB内で実行するとWebLogicではサーバ再起動するまで該当データソースが使えなくなる.
InitialContext ctx = new InitialContext(Const.JNDI_PROPS); DataSource ds = (DataSource) ctx.lookup(Const.XADS_JNDI); Connection conn = ds.getConnection(); Statement stmt = conn.createStatement(); DataSource ds2 = (DataSource) ctx.lookup(Const.XADS_JNDI2); Connection conn2 = ds2.getConnection(); Statement stmt2 = conn2.createStatement(); UserTransaction utx = this.sc.getUserTransaction(); utx.begin(); stmt.executeUpdate("INSERT INTO xasimpletest VALUES (100)"); stmt2.executeUpdate("INSERT INTO xasimpletest2 VALUES (200)"); ResultSet rs = stmt2.executeQuery("SELECT connection_id()"); rs.next(); int connectionId = rs.getInt(1); stmt2.executeUpdate("KILL " + connectionId); Thread.sleep(100); try { utx.commit(); } catch (Exception e) { // expected } conn.close(); // for windows try { stmt2.executeUpdate("SELECT 1"); } catch (Exception e) { // ignore } conn2.close(); ctx.close();
テストなので意図的にDBへの接続をKILLコマンドで切っているわけだが,運用時には何らかの原因により(例えばタイムアウトやネットワーク障害によって)接続が切れた場合,WebLogicでは管理者がサーバを再起動させるまでアプリが動かなくなるんじゃないかな,もしかして.
JBossの場合はこのコードを実行した後も引き続き別のコードからデータソースを利用できるのに.
また爆弾発言しちゃいますよ.
XAテスト解決
一通りのテストに成功.やれやれ.
感想:WebLogicは当初想像していた以上に扱いにくいプロダクトだったよ.上っ面はいいんだけど中身がちょっとJBossよりもクオリティ低いかも.
記念ログあげ.
163 Query XA START 0x0000db50835b7f28edb9,0x4d7953514c20584120436f6e6e656374696f6e20506f6f6c,0xbea1 165 Query XA START 0x0000db50835b7f28edb9,0x4d7953514c20584120436f6e6e656374696f6e20506f6f6c32,0xbea1 163 Query INSERT INTO xasimpletest (number) VALUES (100) 165 Query INSERT INTO xasimpletest (number) VALUES (110) 165 Query SELECT connection_id() 165 Query KILL 165 163 Query XA END 0x0000db50835b7f28edb9,0x4d7953514c20584120436f6e6e656374696f6e20506f6f6c,0xbea1 163 Query XA PREPARE 0x0000db50835b7f28edb9,0x4d7953514c20584120436f6e6e656374696f6e20506f6f6c,0xbea1 163 Query XA ROLLBACK 0x0000db50835b7f28edb9,0x4d7953514c20584120436f6e6e656374696f6e20506f6f6c,0xbea1
UserTransaction.commit()中にどこかのXAResourceでエラーが発生した場合,全体がロールバックされるテスト時のログ(MySQL一般クエリログ).今回はこの間のJBossXAユニットテストと同じように2つのXAResourceをどっちもMySQLにしてやった.WebLogicJMS意味不明だし.
changeUser() そして 問題解決(?)
getXADataSouceした時に以前のConnector/JはchangeUserコマンドを発行していた.changeUserが発行されるとautocommitとかの接続後に設定した内容が初期化される.
つまりこの仕様に立てば,AppServerはサーバ起動時のコネクションプーリング作成の際だけでなく,グローバルトランザクションを発行する際にも再度setAutocommit(false)を呼ばなければならないはずだった.
しかしながらWebLogic側ではそのような呼び出しを行う実装になっておらず,ここに想定通りにテストが通らない原因の1つがあった.
この問題はConnector/Jの未リリース最新版を使うことで回避が可能.さっそくこれを入手して試してみたところ,commit-rollbackともにうまく機能した.
(この問題を回避しないと,XAであるにも関わらずDB接続の実体がautocommitモードに戻ってしまっている(MySQLのデフォルト)のでrollbackメソッドをコンテナ側が読んでもDB側はコミット済みという状況になる)
相変わらずWebLogicJMSは信じがたい動きをしているが,WebLogic+MySQL XAコネクション 2本でのXAテストに変え,この問題をクリアしたことでやっと前進できるような状態になった.このまま上手く行ってくれると良いが.