(精)java.sql.SQLException: No more data to read from socket


dbcp(Oracle)再リンクの問題-Cause:java.sql.SQLException: No more data to read from socket
このNo more data to read from socket問題(ibatis+spring)はよく発生します.
この異常は、通常、接続プールが使用されているため、接続プールから取得したconnectionが失効したりタイムアウトしたりした場合、この接続を使用してデータベース操作を行うと以上の異常が放出されます.解決策は、データベース接続プールがconnectionに戻る前に、connnctionがタイムアウトまたは失効しているかどうかを確認し、そうであればevictというconnectionを返し、使用可能なconnectionを返すことです. 
具体的な構成は以下の通りです.
	
		
		
		
		
		
		
		
		
		
		
		
		
		
			true
		
		
			true
		
		
			true
		
		
			180000
		
		
			360000
		
		
			SELECT 1 FROM SYS.DUAL
		
	

dbcpリンクの説明の比較的詳しい文章を貼ります
データベース・リンクに関するよくある質問:
1.データベースが予期せぬ再起動後、元のデータベース接続プールは古い不要なリンクを自動的に廃棄し、新しいデータベースリンクを確立することができる
2.ネットワークが異常に中断された後、元の確立したtcpリンクは、自動的に切り替えることができるはずです.例えば、Webサイトの演習中にスイッチを再起動すると、ネットワークが瞬時に切断されます.
3.分散型データベースミドルウェア、例えばcobarはタイミングよくアイドルリンクを異常に閉じ、クライアントは半開きのアイドルリンクが現れる.
 
解決策を大まかに考える:
1.sql心拍検査(アクティブ)
2.リンクで试してみると、処理に失败してリンクを舍て、探雷の依頼はいくつか失败します(小我を犠牲にして、大我の精神を完成します)
3.合理的な空きリンクのタイムアウト時間を設定し、半開きリンクを避ける(怠け者モード、半開きリンクを解決する)
 
 
次に、dbcpでどのように実現されるかを見てみましょう.
sql心拍数検査
sql validate構成
 true 
 false 
 false 
select sysdate from dual
1
30000
16
パラメータの説明
  
dbcpはcommons-poolを接続プール管理として採用し、testOnBorrow、testOnReturn、testWhileIdleはpoolが提供するいくつかの検査メカニズムであり、外部フックによってdbcpの関連データベースリンク(validationQuery)チェックをコールバックし、dbcp関連外部フック類:PoolableConnectionFactory、common-pool PoolableObjectFactoryに継承され、dbcpはGenericObjectPoolという入口を通って接続プールのborrow,return処理を行う.
具体的なパラメータの説明:
   1. testOnBorrow:文字通りborrowObjectの処理時に取得したconnectionに対してvalidateObjectチェックを行う
   2. testOnReturn:returnObjectが戻ってきたconnectionに対してvalidateObjectチェックを行うことを意味しますが、個人的にはデータベース接続プールの管理にはあまり意味がないと思います
   3. testWhileIdle:注目のポイント、GenericObjectPoolではpool管理に対して、非同期EveictのTimerTaskタイミングスレッドを制御し(パラメータtimeBetweenEveictionRunsMillis>0を設定可能)、スレッドプール内のリンクをタイミングよくvalidateObjectチェックし、無効なリンクを閉じるとensureMinIdleが呼び出され、リンクを適切に確立し、最小minIdle接続数を保証します.
   4. timeBetweenEvictionRunsMillis、設定されたEvictスレッドの時間、単位ms、0より大きい場合evictチェックスレッドが開きます
   5. validateQuery、検査のsqlを表します
   6. validateQueryTimeoutは、検査の実行時にstatement設定、statementを表す.setQueryTimeout(validationQueryTimeout)
   7. numTestsPerEvictionRunは、毎回の検査リンクの数を表し、maxActiveと同じ大きさに設定することを提案し、毎回すべてのリンクを有効に検査することができる.
Sql心拍検査のいくつかの思考:
1.パフォーマンスの問題.
現在のウェブサイトの応用の大部分のボトルネックはやはりI/Oというブロックで、大部分のI/Oはやはりデータベースのこのレベルで、各要求は10回SQLクエリーを呼び出すことができて、もし取引をしないならば、1つの要求は繰り返しリンクを取得して、もしリンクを取得するたびに、例えばtestOnBorrowでvalidateObjectを行うならば、性能のオーバーヘッドはあまり受け入れられません.一度のSQL操作で0.5~1 msが消去されたと仮定できます(一般的にネットワークリクエストは基本的にこの数です)
2.コストと収益
サイトの異常データベースが再起動され、ネットワークが異常に切断される頻度は非常に低く、一般的にはデータベースのアップグレード、演習メンテナンス時に行われる.また、夜に選択されるのが一般的で、アクセス量が比較的低い要求であり、一般的には当直者が注目しているため、異歩のvalidateObjectは受け入れられる.しかし、1つの前提は、合理的な期間内にデータベースが自動再接続を完了することを保証することです.
 
探雷を頼む
関連構成
dbcp自体のデフォルトサポート、構成不要
原理の説明
common-poolsはborrowObject,returnObjectを介して接続の取得と解放を完了し,通常は1回のリクエストでborrowとreturnがペアであり,借りがあれば返す.
しかしreturnObjectを準備するとき、dbcpはこのobjectが壊れているかどうかを見て、壊れたら直接なくして、直接捨ててしまいます.
 
コードレベル:
1.dbcpでPoolingDataSource(DataSourceインタフェースの実装)がPoolableConnection(dbcp connnection関連pool delegate操作)を呼び出して適切に閉じると、_がチェックされます.conn.isClosed()は、データソースに対してisClosedがtrueに戻るとreturnObjectを呼び出さず、リンクを破棄します.
2. _conn.isClosed()は保険かどうか、jdkのapi記述から:A connection is closed if the method close has been called on it or if certain fatal errors have occurred.中には2つの状況が提供されています.1つはclosedメソッドが呼び出され、もう1つはいくつかの異常が発生し、あいまいなことを言っています.
 
アイドルリンクチェック
関連構成
18000000
true 
180
パラメータの説明
1.m i n v e v i c tableIdleTimeMillis dbcpのデフォルトは30分です.非同期スレッドEveictをオンにする必要があります.そうしないと有効になりません.原理は簡単です.非同期スレッドを通じてconnnctionが前回使用したタイムスタンプをチェックするたびに、このtimeout時間設定を超えているかどうかを確認します.
2.removeAbandoned、removeAbandonedTimeoutは、主にリンクの緊張が発生したときに、removeAbandonedTimeoutを超えていない時間がまだ解放されていないリンクをスキャンし、アクティブにリンクを閉じるために使用されます.
適用状況
1.我々が使用するcobarバックエンドでは、アイドルリンクをタイミングよく閉じる操作があり、デフォルトのアイドルリンクtimeout時間は1時間であり、他のoracle,mysqlとは異なるので、このアイドルリンクのtimeout時間を設定することが重要である.
 
2.一般的には、removeAbandonedが必要な場合がいくつかあります.
*コードはfinallyでconnectionを解放していませんが、sqlmappClientTemplateを使用しています.下位層にはリンクが解放されるプロセスがあります.
*データベースのデッドロックに遭遇しました.以前、バックエンドストレージ・プロシージャがロック・テーブル・オペレーションを行ったため、フロント・クラスタ内の接続プールがすべてブロックされ、後続のビジネス処理はリンクが得られないため、すべての処理に失敗しました.
 
 
c 3 p 0構成について
我々が構成したc 3 p 0のいわゆる自動再接続の3つのパラメータもあり、
30
1000
false
 
個人的には誤導だと思いますが、これらの構成は、poolからリンクを取得するのに最大で一定のtimeout時間しか待たないため、接続プールからリンクを取得するときに、取得に失敗して何度も試してみるだけです.
自動再接続の効果を達成するには、c 3 p 0が要求プローブまたはsql心拍検査機能をサポートし、無効なリンクを自動的に取り除く必要があります. 
c 3 p 0の公式ドキュメントの説明が表示されます.http://www.mchange.com/projects/c3p0/index.html#configuring_recovery
 
最後:
Dbcpは、後でデータベースが選択を駆動するトレンドであり、最後にどのように自動的に再接続するかを選択するかは、私たちのアプリケーションシーンによって異なります.例えば、読み取り専用のwebシステム、バックグラウンドビジネスシステム、タスクシステムの処理方法が異なる可能性があります.
読み取り専用Webシステム:プローブを要求するポリシー、すなわち接続プール数の要求に失敗し、ページのリフレッシュに失敗すればよい.
バックグラウンドビジネスシステム:一般的なビジネスはデータベースの書き込み操作に関連しており、多くのデータは再入力できません.一度の処理に失敗した後、手作業で処理するしかありません.この場合、testOnBorrowやtestWhileIdleのようなsql心拍検査が必要かどうかを考えなければならない.