1

私のJavaコードでは、大量のデータを処理しています。そこで、コードをサーブレットとしてAppEngineのCronJobに移動しました。ある日はうまくいきます。データ量が増えると、cronジョブが機能せず、次のエラーメッセージが表示されます。

2012-09-26 04:18:40.627
'ServletName' 'MethodName': Inside SQLExceptionjava.sql.SQLRecoverableException: 
    Connection is already in use.

I 2012-09-26 04:18:40.741
This request caused a new process to be started for your application, and thus caused 
your application code to be loaded for the first time. This request may thus take 
longer and use more CPU than a typical request for your application.

W 2012-09-26 04:18:40.741
A problem was encountered with the process that handled this request, causing it to 
exit. This is likely to cause a new process to be used for the next request to your 
application. If you see this message frequently, you may be throwing exceptions during 
the initialization of your application. (Error code 104)

この問題を処理する方法は?

4

1 に答える 1

0

この例外は、1 つの接続が複数のスレッド間で共有されている場合に一般的です。これは、次のように、コードが同じブロック内の可能な限り短いスコープで DB リソースを取得して閉じるという標準の JDBC イディオムに従っていない場合に発生します。try-finally

public Entity find(Long id) throws SQLException {
    Connection connection = null; 
    // ...

    try {
        connection = dataSource.getConnection();
        // ...
    } finally {
        // ...
        if (connection != null) try { connection.close(); } catch (SQLException ignore) {}
    }

    return entity;
}

質問に対するあなたのコメント、

@TejasArjunサーブレットInit()メソッドで接続プーリングを使用しました。

あなたがそれを正しい方法でやっているという印象を私に与えません。init()これは、サーブレットのメソッドで DB 接続を取得し、すべての HTTP セッションのすべての HTTP リクエストで同じ接続を再利用していることを示唆しています。これは絶対に正しくありません。サーブレット インスタンスは、webapp の起動時に 1 回だけ作成/初期化され、アプリケーションの存続期間全体にわたって再利用されます。これにより、少なくとも直面している例外が確認されます。

try-finally上に示したように、標準的なイディオムに従って JDBC コードを書き直すだけで、準備は完了です。

以下も参照してください。

于 2013-01-17T03:04:20.930 に答える