PDOを使用する場合の永続的な接続管理の背後にあるルール/ロジックは何ですか?
Webサーバー
DBサーバー
非永続的な接続
<?php
// Open a new connection
// Session created in Oracle
$dbh = new PDO('DSN', 'webuser', 'password');
// webuser is active in v$session with a SID=1
$dbh = NULL;
// webuser removed from v$session
// Manually calling $dbh = NULL; will remove the session from v$session
// OR
// Wait for script EOL so a kill-session command is sent to Oracle?
?>
持続的な接続
<?php
// Open a new connection and make it persistent
// Session created in Oracle
// Is Apache maintaining some sort of keep-alive with Oracle here?
// because I thought php.exe is only alive for the duration of the script
$dbh = new PDO('DSN', 'webuser', 'password', array(PDO::ATTR_PERSISTENT => TRUE));
// webuser is active in v$session with a SID=1
$dbh = NULL;
// webuser is still active in v$session with a SID=1
$dbh = new PDO('DSN', 'webuser', 'password', array(PDO::ATTR_PERSISTENT => TRUE));
// webuser is still active in v$session with a SID=1
// Manually calling $dbh = NULL; does not kill session
// OR
// Script EOL does not kill session
// ^^ this is good, just as expected
?>
ページにアクセスすると、webuser
がSID=1
を取得します
同僚がページにアクセスし、webuser
が追加のSID=2
を取得します<-このページにアクセスする新しいコンピューターのSIDをすすぎ、繰り返し、インクリメントします
新しい訪問者がSID=1
を再利用するべきではありませんか?
すべての回答、提案、代替テストの要求、資料の閲覧へのリンクを歓迎します。
私はしばらくの間RTFMを行っており、グーグルはわずかなAdvantages of Persistent vs. Non-persistent
ブログしか作成していません。
Apacheには1つの親プロセスがあります。このプロセスは、Webサーバーに送信される要求を処理する子プロセスを作成します。 Webサーバーの起動時に開始される子プロセスの初期量は、Apache構成のStartServers
ディレクティブによって構成されます。この数は、ServerLimit
に到達するまで、Webサーバーにヒットするリクエストの量が増えるにつれて、必要に応じて増加します。
PHP(CGIはスクリプトの実行の最後にすべてのリソースが解放されるため、mod_phpとして実行されます)が要求に対してデータベースとの永続的な接続を確立するように指示されている場合、この接続は保持されます現在、保持されている接続は、要求が処理されたApache子プロセスとデータベースサーバー間の接続であり、この正確な子プロセスで処理されているすべての要求で再利用できます。
何らかの理由で(理由を正確に尋ねないでください)、子プロセスが実際の要求よりも長く占有されており、別の要求が着信した場合、親Apacheプロセスは、この要求を(確立されていない)新しい子プロセスにリダイレクトします。これまでのデータベースへの接続。スクリプトの実行中に実行する必要がある場合は、観察したとおりにSIDを上げます。これで、Apacheの2つの異なる子プロセスによって保持される2つの接続があります。
これは多くの問題を引き起こす可能性があることを知っておくことが重要です。エンドレスループが存在する場合や、トランザクションが中止された場合など、スクリプトの実行中に予期しないエラーが発生した場合、接続はブロックされ、再利用できません。また、データベースで使用可能なすべての接続が使用されている可能性もありますが、データベースにアクセスしようとしているApacheサーバーの別の子プロセスがあります。このプロセスは、接続がデータベースまたはApacheによって解放されるまで(タイムアウトまたは自発的に終了するまで)一時的にブロックされます。このページのこのトピックに関する詳細情報: http://www.php.net/manual/en/features.persistent-connections.php
コメントの会話で話し合ったことをすべて正しくまとめ、何も忘れていないことを願っています。もしそうなら、私にヒントを残してください、私はそれを追加します。 :)
編集:
このコメント で言及されている@MonkeyZeusの記事を読み終えたところです。上記で要約したプロセスを説明し、Apacheサーバーを最適化して永続的な接続と連携させる方法に関する有用な情報を提供します。ただし、Oracleデータベースのバックエンドがあってもなくても使用できます。あなたは一見を与えるべきです: http://www.Oracle.com/technetwork/articles/coggeshall-persist-084844.html
php
のマニュアルページから this link の永続的な接続について:
持続的接続とは、スクリプトの実行が終了しても閉じないリンクです。永続的な接続が要求されると、PHPは、同じ永続的な接続(以前に開いたままになっている)がすでに存在するかどうかを確認します。存在する場合はそれを使用します。存在しない場合は、リンク。
もちろん、永続的な接続を使用する理由は、かなり高価な接続の数を減らすことです。 MySQLの方が他のほとんどのデータベースよりもはるかに高速ですが。
永続的な接続を使用しているときに テーブルロック にいくつかの問題があります。
なんらかの理由でスクリプトがロックを解除できない場合、同じ接続を使用する後続のスクリプトは無期限にブロックされ、httpdサーバーまたはデータベースサーバーの再起動が必要になる場合があります。
もう1つは、mysql commit でトランザクションを使用する場合です。
トランザクションブロックは、トランザクションブロックが終了する前にスクリプトの実行が終了した場合、その接続を使用する次のスクリプトにも引き継がれます。どちらの場合でも、register_shutdown_function()を使用して簡単なクリーンアップ関数を登録し、テーブルのロックを解除したり、トランザクションをロールバックしたりできます。
永続的な接続の欠点について この質問 を読むことをお勧めします。