PHP: 持続的データベース接続 - Manual
PHP  
downloads | documentation | faq | getting help | mailing lists | | php.net sites | links | my php.net 
search for in the  
<接続処理セーフモード>
view the version of this page
Last updated: Tue, 21 Dec 2004

第 40章持続的データベース接続

持続的接続は、スクリプトの実行終了時にも閉じられないSQLリンクです。 持続的接続が要求された時、PHPは(前もってオープンされたままになって いる)同じ持続的接続が既にオープンされていないかどうかを確認します。 そして、存在する場合には、それを使用します。存在しない場合には、そ のリンクを作成します。'同じ'接続とは、同じホスト、同じユーザー名、 同じパスワード(利用可能な場合)でオープンされた接続のことを意味しま す。

注意: IMAP拡張モジュールのように、 持続的接続を提供する拡張モジュールは他にもあります。

Webサーバーの動作及び負荷の分散に関して熟知していない人は、持続的接 続において何が行われないかに関してミスを犯す可能性があります。特に、 持続的接続は、同じSQLリンクで'ユーザーセッション'をオープンする機能 やトランザクションを効率的に確立する機能やその他のあらゆる機能を提 供しません。つまり、言いたいことを極めて簡単に述べると、持続的接続 は非持続的接続で使用できない いかなる 機能も提 供しません。

なぜ?

これは、Webサーバーの動作により行われるべきものです。Webページを生 成するためにPHPを利用するWebサーバーには、3種類の方法があります。

最初は、CGI "ラッパー"としてPHPを使用する方法です。このように実行し た場合、PHPインタプリタのインスタンスは、Webサーバーに(PHPページに 関する)ページがリクエストされる度に生成され、破棄されます。リクエス ト毎に破棄されるために、(SQLデータベースサーバーへのリンクのような) 必要な全てのリソースは破棄される際にクローズされます。この場合、持 続的接続を使用することから得るものは何もありません。持続的接続は持 続しないのです。

2番目は、最も一般的ですが、PHPをマルチプロセスWebサーバー(現在は Apacheのみが含まれます)のモジュールとして実行する方法です。マルチプ ロセスサーバーは、通常、実際にWebページを送信する複数のプロセス(子) を管理するプロセス(親)を有しています。リクエストがクライアントから 来ると、親プロセスは、他のクライアントにすでに送信を行っていないク ライアントの一つに渡します。このため、同じクライアントが2番目のリク エストをサーバーに送信した際に最初のではなく他の子プロセスにより送 信が行われる可能性があります。この場合、持続的接続が行うのは、SQLサー バーに接続を行うページを送信する各子プロセスが、最初にSQLサーバーに 接続する場合にのみ、接続を行う必要があるようにすることです。別のペー ジがSQLサーバーに接続要求を出した場合、以前に子が確立した接続を再使 用することが可能です。

最後のは、PHPをマルチスレッドWebサーバーのプラグインとして使用する 方法です。現在、PHP 4 は、ISAPI, WSAPI, NSAPI を(Windows上で)サポー トしており、Netscape FastTrack、Microsoftの Internet Information Server (IIS)、O'Reillyの WebSite Proのようなマルチスレッド型サーバ のプラグインとしてPHPを使用することが可能です。この場合の動作は前記 のマルチプロセス型モデルと同様です。SAPIはPHP 3では使用できないこと に注意して下さい。

持続的接続が機能を全く付加しないとしたら、優れている点はなんでしょ う?

答えはかなり簡単です。効率です。持続的接続は、SQLサーバーへ接続する オーバーヘッドが大きい場合には有効です。このオーバーヘッドが実際に 大きいがどうかは様々な要因に依存します。例えば、データベースの種類、 Webサーバーが動作するのと同じコンピューターで動作しているか、SQLサー バーを動作させているマシンの負荷、等となります。肝心なのは、接続の オーバーヘッドが高い場合、持続的接続は著しいということです。持続的 接続は、SQLサーバーへの接続を要求するページをリクエスト毎に処理する 代わりに子プロセスが動作中の間一回しかサーバーへの接続を行わないよ うにします。このことは、持続的接続をオープンしたプロセス毎にサーバー への持続的接続をオープンするということになります。例えば、20の異なっ た子プロセスがSQLサーバーへの持続的接続を行うスクリプトを実行した場 合、各子プロセス毎にSQLサーバーへの20の異なった接続が行われます。

しかし、気をつけなければならないことが一つあります。それはデータ ベースへの接続数を制限して使用している場合に、持続的な子プロセスの 接続数がその数を超えると問題が発生し得ることです。もしデータベース の同時接続数の制限が16だとして、サーバに多くのアクセスがあったため 17個の子プロセスが接続しようとするとそのうちの一つは接続に失敗しま す。もしスクリプトにコネクションをシャットダウンしないようなバグ( 例えば無限ループ)があると16程度の同時接続しか許容しないデータベース はすぐにダメになってしまいます。使用しているデータベースが、中断さ れた、もしくは使用されていないコネクションをどのように扱うかを確認 してみてください。

警告

持続的接続を使用する際にはまだいくつか心に留めておく必要がある注意 点があります。一つは持続的接続でテーブルをロックする場合にスクリプト が何らかの理由でロックを外し損ねると、それ以降に実行されるスクリプト がその接続を使用すると永久にブロックしつづけてしまい、ウェブサーバか データベースサーバを再起動しなければならなくなるということです。もう 一つはトランザクションを使用している場合に、トランザクションブロック が終了する前にスクリプトが終了してしまうと、そのブロックは次に同じ接 続を使用して実行されるスクリプトに引き継がれる、ということです。 どちらの場合でも register_shutdown_function()を使用してテーブルの ロックを解除したりトランザクションをロールバックする簡単なクリーン アップ関数を登録することができます。しかしそれよりも良い方法は、テー ブルロックやトランザクションを使用するスクリプトでは持続的接続を使用 せず、問題を完全に避けて通ることです(他の箇所で使用する分には問題あ りません)。

重要なことをまとめます。持続的接続は、標準的な接続に1対1の割りつけ を行うように設計されています。このことは、常に 持続的接続を非持続的接続で置きかえ、かつ動作を変更しないということ ができることを意味します。持続的接続は、スクリプトの効率を変える かもしれません(おそらく変えます)が、動作は変更しません!

See also fbsql_pconnect(), ibase_pconnect(), ifx_pconnect(), imap_popen(), ingres_pconnect(), msql_pconnect(), mssql_pconnect(), mysql_pconnect(), ociplogon(), odbc_pconnect(), ora_plogon(), pfsockopen(), pg_pconnect(), sybase_pconnect()も参照してください。



add a note add a note User Contributed Notes
持続的データベース接続
aaryal at foresightint dot com
15-Jan-2004 11:21
this one bit quite a bit of chunk out of my you-know-what. seems like if you're running multiple database servers on the same host (for eg. MySQL on a number of ports) you can't use pconnect since the port number isn't part of the key for database connections. especially if you have the same username and password to connect to all the database servers running on different ports. but then it might be php-MySQL specific. you might get a connection for an entirely different port than the one you asked for.
web at nickSPAMrabinowitz dot com
02-Dec-2003 10:41
This may only pertain to Apache/MySQL:

After several hours of wrestling with MySQL "Access denied" messages, I determined that persistent database connections don't necessarily reflect subsequent privilege changes.

I loaded a PHP script attempting a LOAD DATA statement, and got an "Access denied" error. I granted FILE privileges to the MySQL user, and was able to run LOAD DATA statements from the terminal, but still got "Access denied" from my PHP pages.  When I switched from mysql_pconnect() to mysql_connect(), the problem went away; eventually I restarted apache to kill the persistent connection and switched back to mysql_pconnect(), and now everything works fine.
jean_christian at myrealbox dot com
15-Aug-2002 10:13
If anyone ever wonders why the number of idle db process (open connections) seems to grow even though you are using persistent connections, here's why:

"You are probably using a multi-process web server such as Apache. Since
database connections cannot be shared among different processes a new
one is created if the request happen to come to a different web server
child process."
sebastian at flothow dot de
18-Apr-2000 02:28
Yes, with nonpersistent connections database connections last only while a database-related request is processed, thus reducing the load on the database server.
However, latency will be somewhat higher since a database connection must be opened before a request can be handeled.

<接続処理セーフモード>
 Last updated: Tue, 21 Dec 2004
show source | credits | sitemap | contact | advertising | mirror sites 
Copyright © 2001-2005 The PHP Group
All rights reserved.
This unofficial mirror is operated at: /
Last updated: Mon Mar 14 08:13:06 2005 Local time zone must be set--see zic manual page