2012-02-08 15 views
2

私はデータベース接続プールを持っています。そのプールから接続する消費者がいます。 しかし、彼らの多くは私の接続を戻していないので、私はこれらの消費者を信頼していません。したがって、プールが飢えていて、多くの消費者が無限に待たされています。例えば :例外のため、コンシューマがDB接続プールに接続を戻していません

class Consumer{ 
    void someMethod(){ 
     Connection con=Pool.getConnection(); 
     //some bloody steps which throws exception 
     con.goodBye();//giving back the connection to the pool 
    } 
} 

との接続が常にバック与えられない傲慢のためかもしれません。私は消費者のクラスでプールapiの使用を制限する方法がありません。

私は接続を元に戻すことができますか?(私はコンシューマーを強制する方法がありません) 私はそこに愚かな証明ソリューションはないと信じています。まだ誰もが良い解決策を考え出すことができます。 私が得た1つの解決策は、Consumerクラスで例外が発生したかどうかをチェックすることです。Exceptionが発生した場合は、接続の力を完全に取り戻します。

または、このタイプの典型的なシナリオではあまり一般的ではない新しい革新的なDBPoolデザインパターンがあります(私のケースは非常に一般的だと思いますが、プールに接続を戻すのを忘れることはありません)。 )

+2

これはプログラミングよりも管理上/管理上の問題です。キュービクルとコーディングに座っている世界のすべての問題を解決することはできません。このために、私はプログラミングの悪いクライアントのリストを作り、経営陣にこの問題を提起します。 –

答えて

1

接続オブジェクトを返さず、代わりに接続を表すプロキシオブジェクトを返します。これらのプロキシオブジェクトは、ファイナライズされた時点で、それらが表す接続に別れを示すはずです。プロキシが正しく閉じられないと、最終的にガベージコレクションが行われ、この時点で接続状態が調整されます。

ここに2つの問題があります。まず、GCの前の時間は予測できません。永遠よりも優れていますが、それでもなお非常に長くなることがあります。第2に、ファイナライザ、特にオブジェクトの復活における複雑な呼び出しの副作用に注意してください。オブジェクトがまったく収集されないようにする稀ではあるが醜いシナリオがいくつかあります。

+0

私はこの解決策が頭の中で最も少なくなっていると思います – Arshed

0

例外をキャッチして、catch節で接続を終了しようとしましたか?

class Consumer{ 
    void someMethod(){ 
     Connection con=Pool.getConnection(); 
     try{ 
      //some bloody steps which throws exception 
     }catch(Exception e){ 
      con.goodBye(); 
     } 
     con.goodBye();//giving back the connection to the pool 
    } 
} 

編集:あなたはまた、冗長なコードを削除し、あなたの接続は、すべての場合に閉じますことを確認するfinallyブロックを使用することができます。私はこれがJavaコードであると仮定していますが、C#での経験はありません。

+0

私はあなたに同意します。しかし残念なことに、消費者部分は外部ユーザーによって実装されます。私はプールAPIとそれを消費者に提供することを意味します。 – Arshed

+1

@Arshedそれでは、あなたの責任ではありません。あなたは、消費者が意図的に無視している確立されたAPIを提供しています。 –

+0

ケースはこのようなものです。 1つのmysqlデータベースがあります。このmysqlにはデータベースがない 'N'はありません。私は顧客/クライアントを持っています。彼らは私のプールにふさわしいそれぞれのDBに接続します。 Client1は何らかの接続を取り戻したことはありません.Client2には影響しません。私は同意する、クライアント1が彼の罪のために苦しむことを許可しなさい。しかし、なぜクライアント2 – Arshed

0

私が考えることができる唯一の方法は、コンシューマに接続プールへのアクセスを直接与えるのではなく、独自の接続リストを持つことです。その後、タイムアウト、たとえば60秒後に接続を再要求します。

+0

私はそれを行うことはできますか?その時に消費者が何らかの取引をしている可能性があります。そうすれば、システムが不安定になることがあります。 – Arshed

+0

タイムアウトが必要です。しかし、タイムアウトが短すぎると、他の問題が発生します。そして、ほとんどの接続プールメカニズムは、プールを「直接」露出させません。とにかく...それがポイントです。 –

+0

まず、あなたのシステムは現時点では不安定に聞こえます。 comsumersが本当に1分以上接続している場合は、時間を増やす必要があるかもしれません(Googleが30秒の制限を課すことについて覚えているようです)。 Pool.getConnection();あなたの支配下にある?プールから直接ではなくリストから接続を取得するには、これを再定義します。 – Jaydee

2

これは不正なクライアントコードです。コードは例外の大文字と小文字を処理し、終了すると接続を閉じる必要があります。

あなたのコードから、それが行われていないかどうかを知る方法はありません。それはそれをしない場合は、クライアントコードの欠陥と問題です。

これを制限するには、タイムアウトが必要ですが、最終的にはそれを "解決"しません。

- あなたはこのプールは、複数のクライアント間で共有されていることをコメントで言及

。それは当然責任をあなたに戻します。

各クライアントを一度にX接続のみに制限できますか?この方法では、少なくとも彼らは一度に多くの人を縛ることができます。

それ以外の場合は、クライアントごとに個別のプールを作成できます。そのようなことは問題をスタックに移動するだけですが、関連するロジスティクスに応じて適切かもしれません。

+0

この場合を考慮してください。 私はあなたに同意します。その特定のクライアントに欠陥があります。しかし、n人のクライアントがあり、1人のクライアントが間違ったことをした場合、他のクライアントに影響を与えるべきではありません。 – Arshed

+0

反映するために私の答えを編集します。 –

+0

特定のクライアントの接続数を制限できます。しかし、それは問題を解決しません。別々のプールを分けて問題を解決します。しかし、私はそれが実用的だとは思わない。あまりにも多くの空き接続(他のクライアントに割り当てられている)があっても、特定のクライアントに許可される接続の数を制限します。 – Arshed

1

ここではWeakReferenceを使用していないのですが、ここで接続の弱い参照を返すようにコードを調整できます。接続が切断されると、オブジェクトには参照がありません(WeakHashMapを除く)。これらのオブジェクトを定期的に識別し、スレッドを使用してgoodByeメソッドを呼び出すことができます。

hereは、これをよりよく理解するのに役立つ記事です。

.netまた、これに非常に類似した動作をするWeakReferenceクラスもあります。

+1

この場合、これは役に立たないと思われます。これは、基本的に接続タイムアウトを実装していますが、一般的に使用されるパターンとは異なるパターンです。 –

+0

はい、私は同意します、ここでの問題は、クライアントが基準を遵守していない場合でも、あなたは何かを追跡するために何かを行うことができます..これはそれを行う方法の1つです。いくつかの状況で私のために働いています。 –

+1

これは素晴らしいアイデアだと思います。ありがとうございます – Arshed

関連する問題