Stałe połączenia z bazami danych
Stałe połączenia (persistent connections) to połączenia, które nie są
zamykane po wykonaniu skryptu. Kiedy skrypt próbuje nawiązać stałe
połączenie, PHP sprawdza czy istnieje już identyczne połączenie (otwarte
wcześniej) i jeśli istnieje, używa go. Jeżeli nie, tworzone
jest nowe. Połączenie 'identyczne' to połączenie z tym samym hostem,
z taką samą nazwą użytkownika i hasłem.
Ludzie niezbyt dobrze znający zasady działania serwerów mogą czasem
brać stałe połączenia za coś, czym te nie są. Stałe połączenia
nie stwarzają możliwości otwarcia połączenia dla
konkretnego użytkonika, nie pozwalają na skuteczne
stworzenie systemu transakcji, i nie robią wielu innych rzeczy.
Powiedzmy to jasno, stałe połączenia nie oferują nic
ponad to, co robią 'zwykłe' połączenia.
Dlaczego?
Jest to związane z zasadą działania serwerów. Są trzy sposoby na
które serwer może wykorzystac PHP do generowania stron.
Pierwsza metoda to wykorzystanie PHP jako "wrappera" CGI. Przy wywołaniu
skryptu każdorazowo uruchamiany i niszczony jest egzamplarz PHP. Jako, że
jest on niszczony po każdym wywołaniu, wszystkie zasoby przez niego
posiadane (na przykład połączenia z bazą danych) są tracone. W tym przypadku
używanie stałych połączeń nie przynosi korzyści, one po prostu nie są stałe.
Druga, najpopularniejsza metoda, to uruchomienie PHP jako modułu
w wieloprocesowym serwerze, co obecnie dotyczy jedynie serwera Apache.
Serwer wieloprocesowy zwykle uruchamia jeden proces (rodzica), który
koordynuje inne procesy (potomne) zajmujące się dostarczaniem stron.
Kiedy nadchodzi żądanie od klienta, jest ono przekazywane jednemu z
procesów potomnych, który w danym momencie nie obsługuje innego klienta.
Oznacza to, że gdy ten sam klient wyśle do serwera kolejne żądanie, może
zostać obsłużony przez inny proces niż za pierwszym razem. Stałe połączenie
w tym przypadku oznacza, że każdy proces potomny ustanawia połączenie
z serwerem SQL przy pierwszym wywołaniu strony, która takiego połączenia
używa.
Ostatnia metoda to wykorzystanie PHP jako wtyczki (plug-in) do
serwera wielowątkowego. Obecnie PHP4 zawiera obsługę mechanizmów
ISAPI, WSAPI i NSAPI (w Windows), które umożliwiają uruchomienie PHP
jako wtyczki do wielowątkowych serwerów takich jak Netscape FastTrack
(iPlanet), Microsoft Internet Information Server (IIS) i O'Reilly WebSite
Pro. Zachowanie PHP jest zasadniczo takie samo jak w przypadku opisanego
wcześniej modelu wieloprocesowego.
Skoro stałe połączenia nie dostarczają większej funkcjonalności, do czego
mogą być przydatne?
Odpowiedź jest niezwykle prosta -- wydajność. Stałe połączenia
sprawdzają się w przypadku, gdy koszt nawiązania połączenia z SQL
serwerem jest wysoki. To czy koszt jest duży czy nie zależy od wielu
czynników. Na przykład od typu bazy danych, od tego czy znajduje się
ona na tym samym serwerze, od obciążenia maszyny, która obsługuje serwer
SQL, itd. Jeśli zatem koszt połączenia jest wysoki, stałe połączenia
znacznie pomagają. Sprawiają, że proces potomny łączy się z serwerem SQL
tylko raz podczas swojego życia, zamiast otwierać połączenie za każdym
razem gdy zażąda tego skrypt. Oznacza to, że każdy proces potomny, który
nawiązał stałe połączenie, będzie posiadał własne połączenie z serwerem
bazy danych. Dla przykładu, jeżeli 20 procesów potomnych uruchomi skrypt,
który ustanowi stałe połączenie z serwerem SQL, będziesz mieć 20 różnych
połączeń z serwerem, jedno na każdy proces.
Trzeba jednak zauważyć, że może to mieć swoje ujemne strony w przypadku,
gdy limit połączeń do bazy danych zostanie przekroczony przez stałe
połączenia z procesów potomnych. Jeśli twoja baza danych posiada limit
szesnastu jednoczesnych połączeń, a w danej chwili obciążenie jest
wysokie, siedemnasty proces nie będzie mógł się połączyć. Jeśli twoje
skrypty zawierają błędy, które nie pozwalają zamknąć połączeń (na przykłąd
nieskończone pętle), baza danych z limitem 16 połączeń może szybko zostać
zapchana. Poszukaj w dokumentacji swojej bazy danych w jaki sposób radzi
sobie ona z porzuconymi lub bezczynnymi połączeniami.
Ostrzeżenie
Istnieje kilka zagrożeń, które należy brać pod uwagę decydując się na
używanie stałych połączeń. Jednym z nich jest sytuacja, w której skrypt
blokujący tabelę, z jakiegokolwiek powodu nie może zdjąć blokady. Wtedy
kolejne skrypty korzystające z tego samego połączenia będą zablokowane i
może zajść potrzeba ponownego uruchomienia serwera httpd lub serwera bazy
danych. Kolejne zagrożenie dotyczy transakcji. Jeśli skrypt używający
transakcji zakończy działanie przed zakończeniem bloku transakcji, to
zostanie on (blok) przeniesiony do następnego skryptu. W obu przypadkach
można użyć register_shutdown_function(), aby
zarejestrować funkcję porządkującą, która odblokuje tabele lub wycofa
transakcje. Najlepiej jednak jest zrezygnować ze stałych połączeń w
skryptach używających blokowania tabel lub transakcji.
Istotne podsumowanie. Stałe połączenia zostały zaprojektowane tak, by
odpowiadać zwykłym połączeniom. Oznacza to, że zawsze
możesz zastąpić stałe połączenia zwykłymi i nie zmieni to zachowania
skryptu. Natomiast może zmienić (i zapewne zmieni)
jego wydajność!
Zobacz także fbsql_pconnect(),
ibase_pconnect(), ifx_pconnect(),
ingres_pconnect(),
msql_pconnect(), mssql_pconnect(),
mysql_pconnect(), ociplogon(),
odbc_pconnect(), oci_pconnect(),
pfsockopen(), pg_pconnect() i
sybase_pconnect().