残念なJBossTS
おなじみの2 phase commitです。JTAならアプリがcommitするのはTMに対してじゃなくてjavax.transaction.UserTransactionだ、とかいう類いのKYなツッコミはご遠慮くださいね。イメージですよイメージ。
最近JBossの中に入ってるTMのJBossTSってやつは、自動でクラッシュリカバリします。仕様はこんな感じ。JTAしか使ったことないので他は知らん。
- オンラインで失敗したトランザクションを監視スレッドが定期的に回収し、リカバリを実行します。
- ObjectStateファイルとやら($JBOSS_HOME/server/$conf/data/tx-object-store/....にあるやつ)があれば、AtmicActionRecoveryModuleがRM上に残ったprepared transactionをcommitします。
- ファイルが存在しなければ、XARecoveryModuleがRM上に残ったprepared transactionをrollbackします。
- つまり、1.3:まで終わってるトランザクションはcommit、それ以前のものはrollbackという、一見シンプルな戦略ですが、prepareが途中まで終わっているトランザクションと、ObjectStateファイルが消失したトランザクションの区別はつきません。
- Resource Managerからcommitでエラーが返ったりした場合は、大抵Heuristic扱いでリカバリは諦めます。
- でも、手動でトランザクションをドウコウする手段はありません。(ファイルを直接rmしても大丈夫っぽいけどね)
- JBossTS単体でDLしてくるとObjectStoreBrowserなるものが付属していて、これは手動操作なんかができるものっぽいが、ちょっと試したところではさっぱりまともに動かず。JTAだけでいいのにORBがないとか言ってException吐くわ、表示されるべきペインが表示されないわ。まぁ、JBossASに組み込まれていない時点で意味無し。
ちなみに、1.3:の真っ最中、ファイルを作ってから内容を書き込むまでの間にJBossを(KILL signalとかで)強制終了すると、サイズ0のObectStateファイルが残ってこんな感じにくるくるぱーになっちゃいます。
- [#JBTM-570] Failed to recover with empty Tx log - JBoss Issue Tracker
- ファイルがない場合は何も考えずrollbackするくせに、実装がイマイチなせいで残存するサイズ0ファイルは、「障害でファイルが壊れた場合を考えると何もできない」んですって。笑うとこかこれ?
1.5:と1.6:の間でJBossを強制終了すると、以下略。
超レアケースじゃん、実際には起こらないんじゃネーノ?と思うかもしれませんが、トランザクション流しながらJBossぶっ殺す&起動するを繰り返してると、まー出るわ出るわ。なんでこんなシビアなタイミングの問題がわんさか出るのかしら。
あと、未完のトランザクションがある状態でJBossをぶっ殺して、$JBOSS_HOME/server/$conf/data/tx-object-state/配下を削除して起動すると・・・ご想像の通りです。全部rollbackされちゃいます。
どうもxaRecoveryNodeを設定しないでおけば、XARecoveryModuleによるrollback動作をしなくなるようなので、一応回避はできます。ただ、prepare未完のTxを全部手動で始末しなきゃいけないですけどね。しかもRM個別にね。
こんなの、prepareの前にファイルを作るようにすればいいだけなんだけどなぁ・・・性能のためにトランザクションログを書くのをさぼって、結果信頼性落としてたんじゃ、本末転倒ですよ。いや、消してる時点でトランザクションログじゃないか。ログ書いてくれログ。JBossTSだかJBossTMだかJBossTransactionsだか知らんけど。仕事せい。