2011-07-30 12 views
1

起動時にPostgreSQL(8.4)データベースからアプリケーションメッセージをロードするSpring Beanがあります。 ビーン定義は次のようである: <豆....のinitメソッド=「loadMessages」>予期しないResultSetがSpring Webアプリケーションで閉じられた例外です

コードが前方にかなりまっすぐである:

get a connection (we are using a dbcp pool) 
Create a statement (plain jdbc, nothing special) 
execute the query, get the result set 
while(resultSet.next())){ 
    cacheMap.put(resultSet.getString("column1"), resultSet.getString("column2"));  
} 

コードは、時々、ResultSetが内部閉鎖例外でスローアプリケーションの起動時にループします。 PostgreSQL 8.4.2を使用しても例外なく正常に動作しますが、PostgreSQL 8.4.8を使用している場合はほとんどの場合例外をスローします。
Windows 7または2008サーバー、Tomcat 6.0.32、最新バージョンのJava 1.6、すべてのデータベースサーバーが同じマシン上で実行されている4台のコンピューターでテストしました。 結果セットには、約8000行(2つの列、文字可変(200)および文字可変(1000))が含まれています。 ここで何が間違っていますか?

  • 結果セットの処理が完了する前に、プールが接続を閉じているか、再利用している可能性はありますか?
  • また、データベースのバージョンに関連するものもありますか?

ところで、メッセージはアプリケーションの起動ではなく初めて使用されたときにロードされるように変更されています。正常に動作しています。この例外は、init-methodを使用して、起動時にコードが呼び出された場合にのみ発生します。事前

おかげ

答えて

0

は私の最初に考えたのは、それが完全に初期化されている前に、あなたはSpringコンテナBeanを使用してできることです。これにより、時には一貫性のない動作が発生する可能性があります(設定変更やライブラリの変更があったときに、同じ順序で初期化されないことがあります)。最後の段落は、依存関係の初期化の問題も示しています。

春は最初にどのBeanを初期化するかを決定するためにref配線を使用します。しかし、あなたのinitメソッドが(注入されたbeanを使うのではなく)コンテナbeanにアクセスする場合、Springはそれを知らず、構築されているがまだ初期化されていないbeanにアクセスしているかもしれません。この種の悲しみの典型的な候補は、キャッシュと静的イニシャライザです。

キャッシュコンテナのアクティビティをSpringコンテナの作成後に移動するソリューションは、私にとっては良い解決策のようです。依存関係の初期化の問題で、どのBeanが完全ではないか(接続プールなど)を推測できる場合は、Bean設定で「depends-on」を使用して、最初に他のBeanの初期化を強制できます。

初期化の問題であれば、「結果セットクローズ」例外が発生すると、常にwhile(resultSet.next()))文の最初のヒットになり、あなたのキャッシュには何もありません。物事は正しく初期化されておらず、すぐに失敗するか、物事が正しく初期化され、キャッシュが移入します。キャッシュが部分的に読み込まれ、結果セットエラーが結果セットを読む途中で起こっている場合、初期化理論全体はそれ以上意味をなさない。

+0

あなたの答えをありがとう。我々は春だけで管理されている豆を使用しています。結果セットでクローズされた例外はスローされません。キャッシュには部分的にデータが取り込まれます。たとえば、通常8k行を持つ場合、2k行程度(実際の数値ではありません)を処理した後に例外がスローされます。どういうわけか結果セット、私は文がループ中に閉じていると思う。ドキュメンテーションによると、同じ接続で別のクエリが実行された場合、この文は閉じられます。接続プールは別のクエリを実行する別のスレッドに接続を渡しているかもしれません。しかし、このシナリオは私には意味がありません。 –

関連する問題