[Seasar-user:18304] Re: [S2DBCP,S2DAO] DB(Oracle側)のエラーでコネクションクローズに至った場合再取得について

尾藤 浩嗣 [E-MAIL ADDRESS DELETED]
2009年 8月 17日 (月) 17:50:00 JST


びとうです。

>> どちらということもなく,「例外が発生したとき」です.
>> 上記のような現象は Connection#prepareStatement() で
>> 例外が発生しなかったのではないでしょうか.
すいません。現象の分析が不十分だったのですが、まず、現象を時系列に並べますと、
以下の様になっています(長文申し訳有りません)。

  (1) S2DAOを用いたデータ取得で、DBMS(Oracle)側のエラーが発生
     org.seasar.framework.exception.SQLRuntimeException: [ESSR0071]SQLで例外(ErrorCode=17412, SQLState=99999)が発生しました。
     at org.seasar.framework.util.PreparedStatementUtil.executeQuery(PreparedStatementUtil.java:37)
     ...
    Caused by: java.sql.SQLException: 型の長さが最大を超えています。
        at oracle.jdbc.driver.SQLStateMapping.newSQLException(SQLStateMapping.java:70)
        at oracle.jdbc.driver.DatabaseError.newSQLException(DatabaseError.java:110)
        at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:171)
        at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:227)
        at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:439)
        at oracle.jdbc.driver.T4CMAREngine.buffer2Value(T4CMAREngine.java:2242)
        at oracle.jdbc.driver.T4CMAREngine.unmarshalUB4(T4CMAREngine.java:1189)
        at oracle.jdbc.driver.T4CMAREngine.unmarshalDALC(T4CMAREngine.java:2136)
        at oracle.jdbc.driver.T4C8TTIuds.unmarshal(T4C8TTIuds.java:143)
        at oracle.jdbc.driver.T4CTTIdcb.receiveCommon(T4CTTIdcb.java:169)
        at oracle.jdbc.driver.T4CTTIdcb.receive(T4CTTIdcb.java:126)
        at oracle.jdbc.driver.T4C8Oall.receive(T4C8Oall.java:988)
        at oracle.jdbc.driver.T4CPreparedStatement.doOall8(T4CPreparedStatement.java:194)
        at oracle.jdbc.driver.T4CPreparedStatement.executeForDescribe(T4CPreparedStatement.java:785)
        at oracle.jdbc.driver.T4CPreparedStatement.executeMaybeDescribe(T4CPreparedStatement.java:860)
        at oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:1186)
        at oracle.jdbc.driver.OraclePreparedStatement.executeInternal(OraclePreparedStatement.java:3381)
        at oracle.jdbc.driver.OraclePreparedStatement.executeQuery(OraclePreparedStatement.java:3425)
        at oracle.jdbc.driver.OraclePreparedStatementWrapper.executeQuery(OraclePreparedStatementWrapper.java:1202)
        at org.seasar.extension.jdbc.impl.PreparedStatementWrapper.executeQuery(PreparedStatementWrapper.java:71)
        ... 153 more

  (2) (1)のすぐ後、S2DAOを用いた別のテーブルに対するデータ取得で以下の例外が発生
     org.seasar.framework.exception.SQLRuntimeException: [ESSR0071]SQLで例外(ErrorCode=17002, SQLState=08006)が発生しました。
     at org.seasar.framework.util.PreparedStatementUtil.executeQuery(PreparedStatementUtil.java:37)
     ...
     Caused by: java.sql.SQLException: I/O例外です。: パイプが切断されました
       at oracle.jdbc.driver.SQLStateMapping.newSQLException(SQLStateMapping.java:74)
       at oracle.jdbc.driver.DatabaseError.newSQLException(DatabaseError.java:110)
       at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:171)
       at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:227)
       at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:494)
       at oracle.jdbc.driver.T4CPreparedStatement.executeForDescribe(T4CPreparedStatement.java:796)
       at oracle.jdbc.driver.T4CPreparedStatement.executeMaybeDescribe(T4CPreparedStatement.java:860)
       at oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:1186)
       at oracle.jdbc.driver.OraclePreparedStatement.executeInternal(OraclePreparedStatement.java:3381)
       at oracle.jdbc.driver.OraclePreparedStatement.executeQuery(OraclePreparedStatement.java:3425)
       at oracle.jdbc.driver.OraclePreparedStatementWrapper.executeQuery(OraclePreparedStatementWrapper.java:1202)
       at org.seasar.extension.jdbc.impl.PreparedStatementWrapper.executeQuery(PreparedStatementWrapper.java:71)
	... 152 more

  (3) (2)のすぐ後、S2DAOを用いた別のテーブルに対するデータ取得で以下の例外が発生
     org.seasar.framework.exception.SQLRuntimeException: [ESSR0071]SQLで例外(ErrorCode=17008, SQLState=99999)が発生しました。
       at org.seasar.extension.jdbc.util.ConnectionUtil.prepareStatement(ConnectionUtil.java:52)
     ...
Caused by: org.seasar.framework.exception.SSQLException: [ESSR0072]SQLで例外(SQL=[select * from (略))], ErrorCode={1}, SQLState={2})が発生しました
	at org.seasar.extension.dbcp.impl.ConnectionWrapperImpl.wrapException(ConnectionWrapperImpl.java:534)
	at org.seasar.extension.dbcp.impl.ConnectionWrapperImpl.prepareStatement(ConnectionWrapperImpl.java:154)
	at org.seasar.extension.jdbc.util.ConnectionUtil.prepareStatement(ConnectionUtil.java:50)
	... 152 more
Caused by: java.sql.SQLException: クローズされた接続です。
	at oracle.jdbc.driver.SQLStateMapping.newSQLException(SQLStateMapping.java:70)
	at oracle.jdbc.driver.DatabaseError.newSQLException(DatabaseError.java:110)
	at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:171)
	at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:227)
	at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:439)
	at oracle.jdbc.driver.PhysicalConnection.prepareStatement(PhysicalConnection.java:3046)
	at oracle.jdbc.driver.PhysicalConnection.prepareStatement(PhysicalConnection.java:2961)
	at org.seasar.extension.dbcp.impl.ConnectionWrapperImpl.prepareStatement(ConnectionWrapperImpl.java:150)
	... 153 more


DEBUGレベルのログが残っていないため、論理的なコネクション、物理的なコネクションがいつ
取得、閉じられたかがログから明確にならないのですが、以下の様な動作になると考えても
良いでしょうか?

 ・ (1),(2)は、PreparedStatementUtil#executeQueryでの例外発生で、ここでは物理的なコネクションは
    閉じられない(論理的なコネクションは閉じられる)

 ・ (3) は、ConnectionUtil#prepareStatement での例外発生で、これによりdbcp実装は、
    物理的なコネクションを閉じる(実際にDBとのコネクションはクローズされており、
    dbcpとしてもコネクションインスタンスを解放する)

-以上-

びとうは書きました:
> びとうです。
> 
> ありがとうございます。
> 
>> ちなみに,DB サーバとの間にファイアウォールが
>> あったりしないでしょうか?
>> その場合,S2DBCP のアイドル時間を適切に設定しないと
>> ファイアウォールによってコネクションが切断されやすく
>> なります.
> DBサーバと、アプリケーションサーバ(WebSphere)は同一サーバ
> 内なので、ネットワーク的な問題の可能性は低いのですが、
> DB(Oracle11g)が、ごく稀に内部エラーを起こして例外に至ります。
> 
> -以上-
> 
> Koichi Kobayashi さんは書きました:
>> 小林 (koichik) です.
>>
>> Date:    Wed, 12 Aug 2009 18:49:40 +0900
>> From:    尾藤 浩嗣 <[E-MAIL ADDRESS DELETED]>
>> To:      [E-MAIL ADDRESS DELETED]
>> Subject: [Seasar-user:18265] [S2DBCP,S2DAO] DB(Oracle側)のエラーでコネクションクローズに至った場合再取得について
>>
>>> S2DAOだけでなく、DBCPに関連するかもしれませんが、DBとのコネクション
>>> が上記の様に例外によりクローズした場合、DBCPやS2DAOは、その
>>> JDBC Connectionのインスタンスをこれ以上使用できないものとして
>>> いつかのタイミングで解放する動作をするでしょうか?
>> します.
>> S2DBCP では,例外が発生したコネクションは
>> 即座にクローズして,プールに戻すことは
>> ありません.
>>
>>>   SQLException I/O例外です。パイプが切断されました。
>>>   SQLException クローズされた接続です。
>>>
>>> という例外が発生したのは、S2DAOを用いて(内部的にはPreparedStatement
>>> が使われていると認識しています)DML文を発行した結果でした。
>>> つまり、Connectionのメソッド呼び出しではなく、PreparedStatementの
>>> メソッド呼び出し時の例外に対し、S2DBCPは、Connectionをクローズする
>>> でしょうか?
>> どちらということもなく,「例外が発生したとき」です.
>> 上記のような現象は Connection#prepareStatement() で
>> 例外が発生しなかったのではないでしょうか.
>>
>> ちなみに,DB サーバとの間にファイアウォールが
>> あったりしないでしょうか?
>> その場合,S2DBCP のアイドル時間を適切に設定しないと
>> ファイアウォールによってコネクションが切断されやすく
>> なります.
>>
>> また,以下のドキュメントにある validationQuery
>> および validationInterval を設定すると,プールから
>> 取得したコネクションが生きているか検証するように
>> なります.
>>
>> http://s2container.seasar.org/2.4/ja/jdbc.html
>>
>>
> 
> 
> 
> _______________________________________________
> Seasar-user mailing list
> [E-MAIL ADDRESS DELETED]
> https://ml.seasar.org/mailman/listinfo/seasar-user
> 



Seasar-user メーリングリストの案内