PHP私が取り組んでいるコードベースには、データベース接続を返すユーティリティクラスがあります。実装は次のようになります。
class Database {
private static $conn;
private static $init = false;
public static function connect() {
if (!self::$init) {
$cnf = new Configuration();
self::$conn = new DatabaseConnection($cnf->get('dbname'), $cnf->get('username'), $cnf->get('password'));
self::$init = true;
}
return self::$conn;
}
}
ネットワーク経由で発生する接続を開くために費やす時間が明らかに少なくなるように、この方法で処理が行われました。
このような単一のデータベース接続をインスタンス化し、そのインスタンスをすべての呼び出し元に返すことは、優れたソフトウェアエンジニアリング手法ですか?
番号。
本当にひどいO/Sを使用しているのでない限り(または、正確には、ODBCライブラリおよび/またはデータベースアクセスドライバ/ライブラリ、O/Sの一部である場合とそうでない場合があります)適切な)、あなたのコードは実際にデータベース接続を作成/使用/クローズしていません。データベース接続オブジェクトを作成/使用/クローズしています。一方、基になる接続は、プールで管理されています。
アプリケーションコードが接続を「開く」とき、実際には、プールから接続をフェッチし、そのステータスを確認し、必要な場合にのみ新しい接続を開くようにシステムに指示しています。
接続を「閉じる」とは、実際には、後で再利用するために、またはタイムアウトするまで、接続をプールに返してシステムに通知することを意味します。
接続数、ライフサイクル、タイムアウトなどを管理するには、ODBCクライアント設定を使用するか、接続文字列にパラメータを挿入します。一意の接続文字列ごとに、それらの接続のプールが生成されます。設定。
本当に1つの接続だけが本当に必要な場合は、プールレベルでそのように構成できますが、これはreally時々数千のスレッドを持つWebアプリケーションの悪い考え。
基盤となるO/Sにこれらの接続を管理させます。それはあなたが書くどんなコードよりもずっと上手になるでしょう。
このような単一のデータベース接続をインスタンス化し、そのインスタンスをすべての呼び出し元に返すことは、優れたソフトウェアエンジニアリング手法ですか?
場合によります。
Database
の単一のインスタンスがサービスロケーター経由でアクセスされるのではなく、すべての呼び出し元に注入される限り、それは良い方法です。このようにシングルトンクラスを挿入するのが良い方法である理由は、それらの呼び出し元内のインターフェイスを介して参照できるため、ユニットテストの実行時にモックデータベース接続を提供できるためです。
ここでは、シングルトンパターンを使用して、すべての呼び出し元が接続オブジェクトの同じインスタンスを確実に受信するようにします。 Soundsを使用すると効率的であり、アプリケーションがpurelyシングルスレッドであり、neverが複数の[データベース関連]一度に何か、それはおそらくかなりうまくいくでしょう。これが特に長時間実行されるプログラム(24時間年中無休で実行されるWindowsサービスなど)である場合は、このメソッドに防御コードを追加して、接続が確実に「実行可能」であることを確認することもできます。最後に接続を使用してから、たとえば毎晩のハウスキーピングのためにデータベースがシャットダウンされていないこと。
問題が発生するのは、プログラムがany並列処理の一種であり、イベント駆動型ユーザーインターフェイスで動作するようなもの驚くほどが得られるとすぐです。
これで、データベース接続が使用中で、1つのイベントの処理を処理している間に、ユーザーがアプリケーションをクリックして、オーバーロードされブロックされた接続に対する要求がますます増えています。これで、ユーザーの期待どおりに一度に複数のことを行うことができないため、アプリケーションのパフォーマンスが低下しているように「見えています」。
データベース接続以上のものを使用することは、これらのケースが「より良い」ことです。
ほとんどのオペレーティングシステムでは、自動的に接続プールが行われるため、新しい接続を開くことは簡単ですer操作ですが、それに伴う有限のオーバーヘッドがあります。すべてを1つの接続に順番に押し下げるのが効率的です。それぞれの操作ごとに新しい接続を開始するのはそうではありません。アプリケーションがどの方向に進む必要があるかについて判断コールを行う必要があります。
あなたがその決定に固執しなければならないということではありません! [シングルトン]接続を提供するためのメソッドcouldをファクトリーに変更します。 「時々」と呼ぶと、「1つの」接続オブジェクトが返されます。 「迅速な連続」でそれを呼び出す場合、または接続が「ビジー」であることを検出した場合、新しい接続を返すことを選択する可能性があります。
それはすべて、これがあなたを引き起こす問題の程度に依存します。
はい。
他の回答には、PHPがシングルスレッドでブロックされているという事実が欠けています。通常、一度にプロセスごとに1つのHTTPリクエストを処理します。can複数の接続を使用します本当に必要な場合は一度に、通常は必要ないので、プロセスごとに単一の接続を使用することは完全に問題ありません。
これがたとえばNode.jsである場合、はい、代わりにプーリングを使用する必要があります。