[解決済み] PDOで持続的接続を使用することのデメリットは何ですか?
質問
PDO では、接続を永続化するために
PDO::ATTR_PERSISTENT
属性で指定します。phpのマニュアルによると -
持続的な接続は、スクリプトの終了時に閉じられるのではなく はキャッシュされ、他のスクリプトから接続要求があったときに再利用されます。 同じ認証情報 持続的接続キャッシュを使用すると のたびに新しい接続を確立するオーバーヘッドを回避することができます。 スクリプトはデータベースと通信する必要があり、その結果、より速いウェブ アプリケーションになります。
また、PDO ODBCドライバを使用している間は、ODBCコネクションプーリングの妨げになる可能性があるため、持続的接続を使用しないようマニュアルで推奨しています。
というわけで、どうやらPDOで持続的接続を使うことの欠点は、最後のケースを除いてはなさそうです。しかし、このメカニズムを使用することによる他のデメリット、つまり、このメカニズムがパフォーマンスの低下をもたらす状況、またはそのようなものがあるかどうかを知りたいのです。
解決方法は?
を必ずお読みください。 この回答は以下の通りです。 この問題を解決するための方法を詳しく説明しています。
データベース操作の途中でスクリプトが予期せず終了した場合、 残された接続を取得した次のリクエストは死んだスクリプトが残したものを 拾い上げることになります。 接続は、PHP レベルではなくプロセスマネージャレベル (mod_php では Apache、FastCGI を使用している場合は現在の FastCGI プロセスなど) で保持され、スクリプトが異常終了しても PHP は親プロセスに接続を切断させるような指示を出しません。
死んだスクリプトがテーブルをロックした場合、接続が切れるか、次に接続を取得したスクリプトが自らテーブルのロックを解除するまで、それらのテーブルはロックされたままとなります。
死んだスクリプトがトランザクションの途中だった場合、デッドロックタイマーが作動するまで多くのテーブルがブロックされる可能性があり、その場合でもデッドロックタイマーは問題を引き起こしている古いリクエストではなく新しいリクエストを殺すことができます。
死んだスクリプトがトランザクションの途中だった場合、その接続を取得した次のスクリプトは、トランザクションの状態も取得することになります。 アプリケーションの設計によっては、次のスクリプトが既存のトランザクションをコミットしようとしなかったり、コミットすべきでないのにコミットしたり、ロールバックすべきでないのにロールバックしたりする可能性が非常に高いです。
これは氷山の一角に過ぎません。 スクリプトのリクエストごとに常にダーティコネクションの後始末をすることで、ある程度は軽減されますが、データベースによっては面倒なことになります。 データベース接続の作成を ボトルネックになっているのは を使ったコードプロファイリングを行っていることを意味します。 xdebug および xhprof を使用する必要があります。 ない 持続的な接続は、何かの解決策になると考えています。
さらに、(PostgreSQLを含む)ほとんどの最新のデータベースは、 コネクションプールを行うための独自の方法を採用しており、 PHPベースの単純な持続的接続のような直接的な欠点はありません。
ポイントを明確にするために、私の職場では持続的接続を使用していますが、選択したわけではありません。 私たちは 変 アプリケーションサーバーからデータベースサーバーへの最初の接続が まさに 本来は1秒の何分の一かの時間しかかからないはずなのに、3秒かかっている。 カーネルのバグだと思われます。 この現象はランダムに発生し、オンデマンドで再現できないため、トラブルシューティングを試みることをあきらめ、外注のIT部門もそれを追跡する具体的な能力を持っていませんでした。
とはいえ、倉庫にある数百個の部品を処理するときに、1個の部品に0.5秒ではなく3.5秒かかるとしたら、私たち全員が誘拐されて助けられる前に手を打たねばなりませんでした。 そこで私たちは、自社開発のERP/CRM/CMSを少しばかり起動し、持続的接続の恐ろしさを身をもって体験してみました。 その結果 週間 というのも、一見するとランダムに起こる微妙な小さな問題や奇妙な挙動をすべて追跡するためです。 その結果、ユーザーが熱心にアプリから絞り出した週に一度の致命的なエラーが、テーブルをロックしたり、トランザクションを放棄したり、その他の不運な異常状態を残していることが判明しました。
このお涙頂戴の話には一理あります。 パフォーマンスという名のもとに、想定外のものを壊してしまったのです。 ユーザーから暴動を起こされることなく、通常の接続に戻せる日を心待ちにしています。
関連
-
[解決済み] [Solved] Fatal error: メンバ関数prepare()のNULLでの呼び出し
-
[解決済み】予期せぬ例外。SQLSTATE[HY000] [1045] Access denied for user ****@'localhost' (using password: YES)
-
[解決済み】++と*+の意味は何ですか?
-
[解決済み】未定義の関数mysql_query()をLoginで呼び出す【重複
-
[解決済み】PHP フェイタルエラー。未定義の関数mssql_connect()をコールしています。
-
[解決済み】既に開始されているPHPセッション【重複あり
-
[解決済み】Wordpressの子テーマのstyle.cssが効かない。
-
[解決済み] オートロードとは何ですか; spl_autoload、__autoload、spl_autoload_register はどのように使うのですか?
-
[解決済み] Long-Polling、Websocket、Server-Sent Events (SSE)、Cometとは何ですか?
-
[解決済み] PDOのプリペアドステートメントは、SQLインジェクションを防ぐのに十分ですか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] [Solved] Fatal error: メンバ関数bind_param()のbooleanに対する呼び出し [重複] [重複
-
[解決済み】mysqli_result クラスのオブジェクトを文字列に変換できない
-
[解決済み】DateTimeクラスのオブジェクトを文字列に変換できない
-
[解決済み】Xampp ローカルホスト/ダッシュボード
-
[解決済み】既に開始されているPHPセッション【重複あり
-
[解決済み】count()パラメータは配列かlaravelのcountableを実装したオブジェクトでなければならない
-
[解決済み] Uncaught SyntaxError: JSON の位置 1 に予期しないトークン o があります。
-
MacでPHPを実行した際に、メモリサイズが134217728バイトも消費される問題の解決方法について
-
[解決済み】Fatal error: mysqli_result 型のオブジェクトは使用できません [終了] 。
-
[解決済み] オートロードとは何ですか; spl_autoload、__autoload、spl_autoload_register はどのように使うのですか?