当記事は旧バージョンのDb2 on Cloudを対象としています。現在のDb2 on Cloudについては
https://qiita.com/teruq/items/52a29460441b675bc147
を参照ください。
事象
Db2 on Cloud(に本来は限った話でないのですが)を使っていると、たまに次のようなエラーが出る場合があります。
J2CA0056I: 接続マネージャーは、リソース jdbc/xxxxxxxx のリソース・アダプターから致命的接続エラーを受け取りました。 例外: com.ibm.db2.jcc.am.ClientRerouteException: [jcc][t4][2027][11212][4.24.92] 接続は失敗しましたが、再確立されました。 必要な場合は、特殊レジスター設定がやり直されました。 接続のホスト名または IP アドレス: xxx.xxx.xxx.xxx。 接続のサービス名またはポート番号: 50,001。
理由コード: 1。 障害コード: 2、エラー・コード: ゼロ・バイトがサーバーから読み取られました。。 ERRORCODE=-4498, SQLSTATE=08506
これは、アプリケーションとDb2の間で通信が切断された後にはじめてデータベースへの接続を試みると発生するものです。2回目以降は正常に戻ります。
原因
これは大昔からのあるあるで、コネクションプール使用時にDBとの接続が切れると次の接続でエラーになるというものです。その場合、アプリケーションでは例外をキャッチして再接続するようなコーディングをすべきとされています。まず見たことないですが。
これ自体は普通の話なのですが、Db2 on Cloudを使っているとこの事象がかなり頻繁に発生します。しかしチケットで問い合わせてもまず問題はないと返ってきます。ネットワークを怪しんでも、瞬断程度のエラーは普通に発生するぜと言われてしまいます。
しかし最近わかったのですが、Db2 on Cloudは比較的無邪気に?TKOやHADRをしているようです。そしてそれは我々ユーザーには通知されません。このせいで通信が切れているケースがままあるように見えます。
対応
Db2の接続プロパティに次の設定を追加します。
<properties.db2.jcc ~ enableSeamlessFailover="1"/>
これを付与すると、DB接続時にエラーになると自動的に再接続してくれます。トランザクションの途中でエラーになるとさすがに駄目ですが、多くのケースで接続エラーが軽減されると思われます。必須プロパティですね。