PHP
downloads | documentation | faq | getting help | mailing lists | reporting bugs | php.net sites | links | conferences | my php.net

search for in the

Bezpečný režim> <Obsluha spojení
Last updated: Sat, 24 Mar 2007

view this page in

Kapitola 41. Persistentní databázová spojení

Trvalá spojení jsou SQL spojení, která se nezavírají na konci průběhu skriptu. Při požadavku na trvalé spojení PHP nejdříve zkontroluje, jestli už neexistuje identické spojení (které zůstalo otevřeno z dřívějška) - a pokud existuje, použije ho. Pokud neexistuje, PHP ho otevře. "Identické" spojení je spojení, které bylo otevřeno se stejným serverem, uživatelským jménem a heslem (pokud je zadáte).

Poznámka: Existují i další rozšíření, která vytváří trvalá spojení, například Rozšíření IMAP.

Lidé, kteří nejsou důkladně obeznámeni se způsobem, jakým web servery fungují a distribuují zátěž, mohou pokládat trvalá spojení za něco čím nejsou. Zvláště neumožňují otvírání "uživatelských sessions" na stejném SQL spojení, neumožňují efektivní tvorbu transakcí, a neumožňují spoustu dalších věcí. Dokonce, aby o tom bylo opravdu a důkladně jasno, vám trvalá spojení nedají žádnou funkcionalitu, která by nebyla možná s jejich netrvalými protějšky.

Proč?

To je dáno způsobem, jakým fungují webové servery. Jsou tři způsoby, jakými váš web server může využít PHP ke generování webových stránek.

První metodou je použít PHP jako CGI "obal". V tomto režimu se vytváří a ničí jedna instance PHP interpretru pro každý požadavek (na PHP strnánku) na vašem web serveru. Protože je zničena po obsloužení požadavku, všechny zdroje, které získá (jako třeba spojení s databázovým serverem) jsou při jejím zničení zavřeny. V tomto případě pokusem o použití trvalých spojení nic nezískáte - prostě nevydrží.

Druhou, a nejpopulárnější, metodou, je provozovat PHP jako modul v multiprocesním web serveru, což je množina, která v současnosti obsahuje pouze Apache. Multiprocesní web server má typicky jeden proces (rodiče), který řídí skupinu procesů (svých dětí), které dělají vlastní práci - servírují stránky. Každý požadavek, který přijde od klienta, je obsloužen jedním z dětí, které právě neobsluhuje jiného klienta. To znamená, že když stejný klient vznese další požadavek na stejný server, tento může být obsloužen jiným dětským procesem než ten první. Trvalá spojení zajišťují, aby se každý dětský proces musel na váš SQL server přihlásit pouze při prvním odeslání stránky, která takové spojení využívá. Když spojení s SQL serverem vyžaduje další stránka, může použít spojení, které toto dítě otevřelo už dříve.

Poslední metodou je použít PHP jako plug-in v multivláknovém web serveru. Aktuálně PHP 4 má tuto podporu pro ISAPI, WSAPI a NSAPI (na Windows), což umožnuje používat PHP jako plug-in v multivláknových serverech jako Netscape FastTrack (iPlanet), Microsoft Internet Information Server (IIS), a O'Reilly's WebSite Pro. Chování je stejné jako u multiprocesním modelu popsaném dříve. Podpora pro SAPI není dostupná v PHP 3.

Pokud trvalá spojení neposkytují žádnou přidanou funkcionalitu, k čemu jsou dobrá?

Odpověď na tuto otázku je velmi jednoduchá - efektivita. Trvalá spojení jsou dobrá, pokud má tvorba spojení s vaším SQL serverem vysokou režii. Reálná výše této režie záleží na mnoha faktorech. Například jaký je to typ databáze, jestli sídlí na stejném počítači jako váš webserver, jak zatížený je stroj, na kterém váš SQL server běží a tak dále. Pointa je, že pokud je spojovací režie vysoká, trvalá spojení vám znatelně pomohou. Umožní dětskému procesu připojit se pouze jednou za celý jeho životní cyklus místo každého zpracování stránky, která vyžaduje spojení s SQL serverem. To znamená, že každé dítě, které otevřelo trvalé spojení, bude mít otevřené vlastní trvalé spojení se serverem. Pokud například máte 20 dětských procesů, které spustily skript, který otevřel trvalé spojení s vaším SQL serverem, máte 20 nezávislých spojení s SQL serverem, po jednom z každého dítěte.

Všimněte si nicméně, že to může mít nevýhody, pokud používate databázi s omezeným počtem připojení, který trvalá spojení dětí překročí. Pokud má vaše databáze limit 16 současných připojení, a v rušném okamžiku se pokusí připojit 17 dětských procesů, jednomu se to nepodaří. Pokud máte ve svých skriptech chyby, které brání zavírání spojení (např. nekonečné smyčky), databáze s pouhými 32 spojeními bude brzy zaplavena. Vyhledejte si v dokumentaci vaší databáze informace o obsluze opuštěných nebo nečinných spojení.

Varování

Zde je několik dodatečných námitek, které se usadily v mysli během používání trvalých spojení. Jedna z nich je, když používáte zamknuté tabulky při trvalém spojení a skript z jakéhokoli důvodu nemůže uvolnit zámek, pak následující skript, který používá stejné spojení, bude nejspíše na trvalo zablokován a možná bude nutné, abyste pokaždé restartovali http server nebo databázový server. Dále pak v případě použití transakcí se transakční blok přenese i do dalšího skriptu používajícího stejné spojení, pokud jeho vykonání končí dříve než transakční blok. V každém případě můžete použít register_shutdown_function() k registraci a jednoduchému vyčištění funkce pro odemknutí tabulek nebo zrušení běžící transakce (roll back). Nejlépe se problému vyvarujete úplně nepoužíváním trvalých spojení ve skriptech, ve kterých se zamykají tabulky nebo používají transakce (můžete je stále používat na mnohých dalších místech).

Důležitý souhrn. Trvalá spojení byla navržena tak, aby odpovídala jedna k jedné normálním spojením. To znamená, že byste vždy měli být schopni nahradit trvalá spojení netrvalými beze změny fungování vašeho skriptu. Může to (a pravděpodobně bude) mít vliv na efektivitu tohoto skriptu, ale ne jeho chování!

Dále také: fbsql_pconnect(), ibase_pconnect(), ifx_pconnect(), imap_popen(), ingres_pconnect(), msql_pconnect(), mssql_pconnect(), mysql_pconnect(), OCIPLogon(), odbc_pconnect(), Ora_pLogon(), pfsockopen(), pg_pconnect() a sybase_pconnect().



Bezpečný režim> <Obsluha spojení
Last updated: Sat, 24 Mar 2007
 
add a note add a note User Contributed Notes
Persistentní databázová spojení
christopher dot jones at oracle dot com
26-Jun-2007 10:46
For the oci8 extension it is not true that " [...] when using transactions, a transaction block will also carry over to the next script which uses that connection if script execution ends before the transaction block does.".  The oci8 extension does a rollback at the end scripts using persistent connections, thus ending the transaction.  The rollback also releases locks. However any ALTER SESSION command (e.g. changing the date format) on a persistent connection will be retained over to the next script.
andy at paradigm-reborn dot com
20-Feb-2007 08:13
To those using MySQL and finding a lot of leftover sleeping processes, take a look at MySQL's wait_timeout directive. By default it is set to 8 hours, but almost any decent production server will have been lowered to the 60 second range. Even on my testing server, I was having problems with too many connections from leftover persistent connections.
whatspaz at g NO dot SPAM mail dot c o m
26-Nov-2006 03:02
in response to web at nick, have you tried FLUSH PRIVILEGES. this should reload those privileges.
RQuadling at GMail dot com
06-Mar-2006 03:43
If you have multiple databases on the same server AND you are using persistent connections, you MUST prefix all the table names with the specific database name.

Changing the database using the xxx_select_db functions alters the database for the connection for all users who are sharing that connection (assuming PHP is running shared and not CGI/CLI).

If you have 2 databases (live and archive) and your script is talking to both, you cannot use 2 persistent connections and change the database for each one.

Internally, persistent connections are used even if you do not specify that you want to use persistent connections. This is why new_link was added to mysql_connect/mssql_connect (PHPV4.2.0+).
fabio
12-Jan-2006 03:54
You can in fact provide a port for the connection, take a look at http://de2.php.net/manual/en/function.mysql-pconnect.php#AEN101879

Just use "hostname:port" for the server address.
aaryal at foresightint dot com
15-Jan-2004 03: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 02: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 03: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 07: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.

Bezpečný režim> <Obsluha spojení
Last updated: Sat, 24 Mar 2007
 
 
show source | credits | stats | sitemap | contact | advertising | mirror sites