- PR -

LANケーブルを抜いた時のSQLException取得方法について

投稿者投稿内容
takataka
会議室デビュー日: 2008/06/12
投稿数: 4
投稿日時: 2008-06-12 17:47
初めて質問させて頂きます。

開発環境は、
Tomcat5.5
DB:oracle10g
サーバA(WEBサーバ)
サーバB(DBサーバ)

現在、DataSourceを使ってDBアクセスしているのですが、
サーバBのLANケーブルを抜いた時にSQLExceptionを取得できずに困っております。

コンテキスト.xmlで
<Resource
  ・
  ・
maxWait="5000"
  ・
  ・
/>
は設定しています。

但し、以下の条件の場合はLANケーブルを抜いていてもSQLExcepitonを取得できます。
1.tomcat起動後の最初のリクエスト時
2.LANケーブルを抜いてから30分以降のリクエスト時

つまりは、LANケーブルが抜けてから30分以内のリクエストに対して、SQLExceptionを取得できずに困っている状態です。

質問が言葉足らずかとは思いますが、
どなたかご教授宜しくお願い致します。

Java僧
ぬし
会議室デビュー日: 2003/11/06
投稿数: 261
投稿日時: 2008-06-13 08:46
コネクションプールと関係していそうですね。
maxWaitを指定する意図はなんですか?
他のパラメタをどう指定しているのかわかりませんが、
TomcatのコネクションプールはCommons-DBCPなので、
この辺のパラメタでチューニングすることで、
すぐに返るようにもできると思います。
http://commons.apache.org/dbcp/configuration.html
http://tomcat.apache.org/tomcat-5.5-doc/jndi-resources-howto.html

_________________
「ご教授」はできません
takataka
会議室デビュー日: 2008/06/12
投稿数: 4
投稿日時: 2008-06-13 10:50
返信ありがとうございます。

maxWaitは指定時間内に接続が使用可能にならなければエラーを返すようなので記述しています。
(コネクションが全て使われている場合だから、LANケーブルが抜けて接続ができなのとは関係ないかもしれませんね)

コンテキストxmlに
removeAbandoned="true"
removeAbandonedTimeout="60"
も設定しているのですがこの件には効果が無いようです。

LANケーブルが抜けたということは、
TCP/IPとかsocketとかそいうレベルで対応を考えなければならないのでしょうか?

以上、どうぞ宜しくお願い致します。
ranco
大ベテラン
会議室デビュー日: 2007/11/02
投稿数: 112
投稿日時: 2008-06-13 12:11
> TCP/IPとかsocketとかそいうレベルで対応を考えなければならないのでしょうか?
このレベルでも、connection timeoutかread timeoutが標準の対策ですし、これらをマップしたタイムアウト手段は、DataSourceにもStatementにも提供されていますね。
takataka
会議室デビュー日: 2008/06/12
投稿数: 4
投稿日時: 2008-06-13 15:07
返信ありがとうございます。

racco様のおっしゃるとおりで、
DataSourceのsetLoginTimeoutを利用することで対応できるのではないかと思っているのですが、setLoginTimeoutを実装するとUnsupportedOperationExceptionが発生してしまいます。

ソースは以下です。
***************************************
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.sql.DataSource;

InitialContext ctx = new InitialContext();
DataSource ds = (DataSource)ctx.lookup("java:/comp/env/jdbc/myoracle");
ds.setLoginTimeout(20);
ds.getConnection();
***************************************

setLoginTimeoutを利用できるようにするにはどのようにしたら良いのでしょうか?
そもそも、なぜUnsupportedOperationExceptionかがわかりません。

お手数ではありますが、ご教授のほど宜しくお願い致します。


Java僧
ぬし
会議室デビュー日: 2003/11/06
投稿数: 261
投稿日時: 2008-06-13 15:26
maxWaitは「コネクションが全て使われている場合だから、LANケーブルが抜けて接続ができなのとは関係ないかもしれませんね」は自分も同じことを思っていました。

先ほどポイントしたDBCPのドキュメントは読みましたか?
validationQueryとそれをコントロールする各種プロパティは試しましたか?
takataka
会議室デビュー日: 2008/06/12
投稿数: 4
投稿日時: 2008-06-13 16:44
Java僧様
返信ありがとうございます。

「先ほどポイントしたDBCPのドキュメントは読みましたか?」
→はい。ただ英語がそれほど得意ではありませんのであまり理解はできておりません。

context.xmlは以下です。
***************************************
<Resource
auth="Container"
name="jdbc/myoracle"
type="javax.sql.DataSource"
driverClassName="oracle.jdbc.driver.OracleDriver"
maxIdle="25"
maxWait="5000"
removeAbandoned="true"
validationQuery="select Sysdate from Dual"
removeAbandonedTimeout="300"
maxActive="25"
factory="org.apache.tomcat.dbcp.dbcp.BasicDataSourceFactory"/>
</Context>
***************************************

最初から提示していればよかったですね。申し訳有りません。

「validationQueryとそれをコントロールする各種プロパティは試しましたか?」
→validationQueryは設定していました。
ただ、timeBetweenEvictionRunsMillis 等の設定はしていなかったのですが、
調べてみると、これは監視スレッド関連のようで、LANが抜けて30分以内のリクエストをターゲットとしているため、リクエストを受けた時点で接続の有効性を確認する必要があると思うのですが。

validationQueryを設定するだけでは駄目なのでしょうか。

以上、どうぞ宜しくお願い致します。







Java僧
ぬし
会議室デビュー日: 2003/11/06
投稿数: 261
投稿日時: 2008-06-13 17:53
試す環境がないので、「試してみてください」しか書けません・・・

「リクエストを受けた時点で接続の有効性を確認する必要がある」はそのとおりですね。
testOnBorrowがそれに相当するプロパティのようですが、これは初期値でtrueですね。
うまく機能していないのでしょうか。

testWhileIdleプロパティをtrueにするとどうでしょう?
「プールでアイドル中→LAN切断→アイドル中のコネクションをつかむ」動作が問題のようですから、LAN切断の後にアイドル中のコネクションをバリデートするのも有効だと思います。
timeBetweenEvictionRunsMillisはobject evictorの制御パラメタのようですから、testWhileIdleと一緒に指定する必要がありますね。

スキルアップ/キャリアアップ(JOB@IT)