[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 メーリングリストの案内