QA@IT
«質問へ戻る

質問を投稿

DBのgetConnection()に失敗しTomcatが無応答状態になる件

こんにちは、お世話になっております。
今回、下記の件ご相談いたしたく、投稿いたしました。

数回、以下のようなメソッドでSQLを実行すると、
Tomcatが完全に応答しなくなるという現象に悩まされています。
仕様変更などがあり、変更前より若干複雑なSQLに変更したのですが、
変更前は、何の問題もありませんでした。

【環境】
・Tomcat6
・Struts2.1
・Spring2.0
・JRE1.6
・Oracle9.2
・Oracle JDBC Driver ojdbc6.jar

【該当メソッド】
public XXXObject select(String id) throws SQLException {
    XXXObject xxxobj = null;

    Connection con = null;
    PreparedStatement pStmt = null;
    ResultSet rs = null;
    StringBuffer strSQL = new StringBuffer();

    // 実際はもっと複雑なSQL
    strSQL.append("SELECT COL1, COL2 FROM DMYTABLE WHERE ID = ? ");

    try {
        この部分で応答しない。----->>>con = source.getConnection();

        pStmt = con.prepareStatement(strSQL.toString());

        pStmt.setString(1, id);

        rs = pStmt.executeQuery();
        if(rs.next()) {
            xxxobj = getEntityElem(rs);
        }
    } catch(SQLException e) {
        throw e;
    } finally {
        rs.close();
        pStmt.close();
        con.close();
    }

    return xxxobj;
}

Tomcatのスレッドダンプを取得してみたところ、下記のような怪しい部分かありました。
DBCPのコネクションプールのサイズが上限(maxActive)に達し、
getConnection()に失敗していることで応答しない状態になっているようです。
どうも、コネクションのリークが発生しているようなのですが、
close()を行っているにもかかわらず、どのような原因でリークが発生するのでしょうか?

【スレッドダンプ抜粋】
"http-8080-2" daemon prio=6 tid=0x05669c00 nid=0x79c in Object.wait() [0x05cdd000..0x05cdfd18]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on (a org.apache.tomcat.dbcp.pool.impl.GenericObjectPool)
at java.lang.Object.wait(Object.java:485)
at org.apache.tomcat.dbcp.pool.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:942)
- locked (a org.apache.tomcat.dbcp.pool.impl.GenericObjectPool)
at org.apache.tomcat.dbcp.dbcp.PoolingDataSource.getConnection(PoolingDataSource.java:96)
at org.apache.tomcat.dbcp.dbcp.BasicDataSource.getConnection(BasicDataSource.java:880)
at 該当メソッドselect
at 該当メソッドselect呼び出し
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)

※以下略

DBCPのコネクションプールのサイズの上限(maxActive)を増やせばいいのですが、
どうも納得できないでいます。
どなたか同じような現象にあわれたかたとかいらっしゃいますか?
少しでもヒントをいただきたく、投稿させていただきました。
[ メッセージ編集済み 編集者: よしお 編集日時 2009-03-13 17:38 ]

質問者:よしお

こんにちは、お世話になっております。
今回、下記の件ご相談いたしたく、投稿いたしました。

数回、以下のようなメソッドでSQLを実行すると、
Tomcatが完全に応答しなくなるという現象に悩まされています。
仕様変更などがあり、変更前より若干複雑なSQLに変更したのですが、
変更前は、何の問題もありませんでした。

【環境】
・Tomcat6
・Struts2.1
・Spring2.0
・JRE1.6
・Oracle9.2
・Oracle JDBC Driver ojdbc6.jar

【該当メソッド】
public XXXObject select(String id) throws SQLException {
    XXXObject xxxobj = null;

    Connection con = null;
    PreparedStatement pStmt = null;
    ResultSet rs = null;
    StringBuffer strSQL = new StringBuffer();

    // 実際はもっと複雑なSQL
    strSQL.append("SELECT COL1, COL2 FROM DMYTABLE WHERE ID = ? ");

    try {
        この部分で応答しない。----->>>con = source.getConnection();

        pStmt = con.prepareStatement(strSQL.toString());

        pStmt.setString(1, id);

        rs = pStmt.executeQuery();
        if(rs.next()) {
            xxxobj = getEntityElem(rs);
        }
    } catch(SQLException e) {
        throw e;
    } finally {
        rs.close();
        pStmt.close();
        con.close();
    }

    return xxxobj;
}

Tomcatのスレッドダンプを取得してみたところ、下記のような怪しい部分かありました。
DBCPのコネクションプールのサイズが上限(maxActive)に達し、
getConnection()に失敗していることで応答しない状態になっているようです。
どうも、コネクションのリークが発生しているようなのですが、
close()を行っているにもかかわらず、どのような原因でリークが発生するのでしょうか?

【スレッドダンプ抜粋】
"http-8080-2" daemon prio=6 tid=0x05669c00 nid=0x79c in Object.wait() [0x05cdd000..0x05cdfd18]
   java.lang.Thread.State: WAITING (on object monitor)
	at java.lang.Object.wait(Native Method)
	- waiting on <0x2382be00> (a org.apache.tomcat.dbcp.pool.impl.GenericObjectPool)
	at java.lang.Object.wait(Object.java:485)
	at org.apache.tomcat.dbcp.pool.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:942)
	- locked <0x2382be00> (a org.apache.tomcat.dbcp.pool.impl.GenericObjectPool)
	at org.apache.tomcat.dbcp.dbcp.PoolingDataSource.getConnection(PoolingDataSource.java:96)
	at org.apache.tomcat.dbcp.dbcp.BasicDataSource.getConnection(BasicDataSource.java:880)
	at 該当メソッドselect
	at 該当メソッドselect呼び出し
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
	at java.lang.reflect.Method.invoke(Unknown Source)

	※以下略

DBCPのコネクションプールのサイズの上限(maxActive)を増やせばいいのですが、
どうも納得できないでいます。
どなたか同じような現象にあわれたかたとかいらっしゃいますか?
少しでもヒントをいただきたく、投稿させていただきました。
<font size="-1">[ メッセージ編集済み 編集者: よしお 編集日時 2009-03-13 17:38 ]</font>

質問者:よしお