Главная Статьи Написать
 
Начнём
Введение
Инсталяция
Конфигурирование
Безопасность
Справочник Языка
Базовый синтаксис
Типы
Переменные
Константы
Выражения
Операции
Структуры управления
Функции
Классы и Объекты
Ссылки. Разъяснение.
Возможности
Обработка Ошибок
Создание изображений и манипуляции с ними
HTTP-аутентификация в PHP
Куки
Обработка загрузки файлов
Использование удалённых файлов
Обслуживание соединений
Постоянные соединения с базами данных
Безопасный режим
Использование PHP из командной строки
Функции. Справочник.
Функции, специфические для Apache
Array-функции
Aspell-функции [не рекомендуются]
BCMath математические функции произвольной точности
Bzip2 Compression-функции
Calendar-функции
CCVS API-функции
Функции поддержки COM для Windows
Class/Object-функции
ClibPDF-функции
Crack-функции
CURL, Client URL Library-функции
Cybercash payment-функции
Crédit Mutuel CyberMUT-функции
Cyrus IMAP -функции администрирования
Функции типов символов
Функции абстрактного слоя БД (dbm-стиль)
Дата и Время
dBase-функции
DBM-функции
dbx-функции
DB++-функции
Direct IO-функции
Функции директорий
DOM XML-функции
.NET-функции
Обработка ошибок и логинг
FrontBase-функции
filePro-функции
Функции файловой системы
Forms Data Format-функции
FriBiDi-функции
FTP-функции
Функции работы с функциями
Gettext
GMP-функции
HTTP-функции
Hyperwave-функции
Hyperwave API-функции
ICAP-функции [не рекомендуются]
iconv-функции
Image-функции
IMAP, POP3 и NNTP-функции
Informix-функции
InterBase-функции
Ingres II-функции
IRC Gateway-функции
Java
LDAP-функции
Mail-функции
mailparse-функции
Mathematical-функции
Многобайтные строки
MCAL-функции
Mcrypt Encryption-функции
Mhash-функции
Mimetype-функции
Microsoft SQL Server-функции
Ming-функции для Flash
Прочие функции
mnoGoSearch-функции
mSQL-функции
MySQL-функции
Mohawk Software -функции обработчика сессии
muscat-функции
Network-функции
Ncurses -функции управления терминалом
Lotus Notes-функции
Unified ODBC-функции
Oracle 8-функции
OpenSSL-функции
Oracle-функции
Ovrimos SQL-функции
Управление выводом
Перегрузка свойств объектов и вызовов методов
PDF-функции
Verisign Payflow Pro-функции
PHP. Опции & Информация
POSIX-функции
PostgreSQL-функции
Управление процессом
Выполнение программы
Printer-функции
Pspell-функции
GNU Readline
GNU Recode-функции
Функции регулярных выражений (Perl-совместимые)
qtdom-функции
Функции регулярных выражений (POSIX расширенная)
Semaphore, Shared Memory и IPC-функции
SESAM database-функции
Обслуживание сессий
Shared Memory-функции
Shockwave Flash-функции
SNMP-функции
Socket-функции
String-функции
Sybase-функции
URL-функции
Функции переменных
vpopmail-функции
W32api-функции
WDDX-функции
XML parser-функции
XMLRPC-функции
XSLT-функции
YAZ-функции
YP/NIS-функции
Zip File-функции (доступ только для чтения)
Zlib Compression-функции
Расширение PHP 4.0
Обзор
Возможность расширения
Строение исходного кода
Система автоматического построения РНР
Создание расширений
Использование расширений
Решение проблем
Исходные Ресурсы. Обсуждение.
Приём аргументов
Создание переменных
Дублирование содержимого переменной: конструктор Copy
Возвращаемые значения
Печать информации
Startup и Shutdown-функции
Вызов пользовательских функций
Поддержка файлов инициализации
Что дальше?
Справочник: некоторые макросы конфигурации
Макросы API
FAQ: Frequently Asked Questions
Общая информация
Списки рассылки
Получение PHP
Вопросы о базах данных
Инсталяция
Проблемы построения
Использование PHP
PHP и HTML
PHP и COM
PHP и другие языки
Переход от PHP 2 к PHP 3
Переход от PHP 3 к PHP 4
Другие вопросы
Приложения
История PHP и смежных проектов
Переход от PHP 3 к PHP 4
Переход от PHP/FI 2 к PHP 3
Отладка PHP
Расширение PHP
Список псевдонимов функций
Список зарезервированных слов
Список типов ресурсов
Список лексем разборщика
Об этом учебнике




Глава 22. Постоянные соединения с базами данных

Постоянные соединения это SQL-ссылки, которые не закрываются по окончании работы скрипта. Когда постоянное соединение запрашивается, PHP проверяет, имеется ли уже идентичное постоянное соединение (которое осталось открытым после предыдущего запроса), и, если имеется, использует его. Если не имеется, РНР создаёт ссылку. 'Идентичным' является соединение, которое было открыто с тем же хостом, с тем же username и с тем же password (если имеются).

Примечание: имеются другие расширения, которые предоставляют постоянные соединения, такие как IMAP.

Те, кто не вполне знакомы со способами работы web-серверов и распределением нагрузки, могут ошибочно посчитать постоянным соединением соединение, таковым не являющееся. Постоянные соединения не дают возможности открывать 'user sessions' по той же самой SQL-ссылке, они не дают возможности эффективно строить транзакции и не делают ещё много чего. Фактически, чтобы внести полную ясность, постоянные соединения не предоставляют никакой функциональности, которая была бы возможна в их не-постоянных собратьях.

Патщему?

Это зависит от способа работы web-серверов. Есть три способа использования РНР вашим web-сервером для генерации web-страниц.

Первый метод - использование PHP как CGI "wrapper/оболочки". При этом экземпляр PHP-интерпретатора создаётся и разрушается для каждого запроса страницы (PHP-страницы) к вашему web-серверу. Поскольку он уничтожается после выполнения каждого запроса, при этом закрываются все ресурсы, которые он использовал (такие как ссылка на SQL-сервер БД). В этом случае вы ничего не получите от использования постоянных соединений - они просто не существуют.

Второй, самый популярный метод, - запускать PHP как модуль в многопроцессном web-сервере, которым на данный момент является только Apache. На многопроцессном сервере обычно имеется один процесс (parent/родительский), координирующий работу набора других процессов (его потомков), которые фактически выполняют работу по обслуживанию web-страниц. При поступлении каждого запроса от клиента, запрос направляется одному из дочерних процессов, который в данный момент не обслуживает другого клиента. Это означает, что, когда тот же самый клиент выполняет второй запрос к серверу, он может быть обработан другим дочерним процессом, а не тем, который был в первый раз. При этом постоянное соединение делает так, что каждый дочерний процесс должен соединиться с вашим SQL-сервером в первый раз при обслуживании страницы, которая использует это соединение. Если другая страница затем требует установления соединения с SQL-сервером, она может использовать соединение, которое дочерний процесс установил ранее.

Третий метод - использовать PHP как plug-in на многопоточном web-сервере. В настоящее время в PHP 4 имеется поддержка ISAPI, WSAPI и NSAPI (под Windows), которые все позволяют использовать PHP как plug-in на многопоточных серверах, таких как Netscape FastTrack (iPlanet), Microsoft Internet Information Server (IIS) и O'Reilly WebSite Pro. Поведение будет точно таким же, как и для многопроцессной модели, рассмотренной ранее. Обратите внимание, что поддержка SAPI отсутствует в PHP 3.

Если постоянные соединения не имеют дополнительной функциональности, то чем они тогда хороши?

Ответ предельно прост - своей эффективностью. Постоянные соединения пригодятся, если велика нагрузка при создании большого количества ссылок на ваш SQL-сервер. То, насколько реально велика эта нагрузка, зависит от многих факторов. Например, какого типа БД, находится ли она на том же компьютере, что и ваш web-сервер, насколько загружена машина, на которой установлен SQL-сервер, и так далее. Важно то, что, если нагрузка по созданию соединений велика, постоянные соединения могут оказать существенную помощь. Они позволяют дочернему процессу соединиться только один раз для каждого жизненного цикла, вместо того чтобы делать это каждый раз при обработке страницы, которой нужно соединение с SQL-сервером. Это значит, что каждый дочерний процесс, который открыл постоянное соединение, будет иметь своё собственное постоянное соединение с сервером. Например, если у вас 20 дочерних процессов, которые запустили скрипт, выполняющий постоянное соединение с вашим SQL-сервером, у вас будет 20 различных соединений с SQL-сервером, одно для каждого дочернего процесса.

Заметьте, однако, что этот подход имеет и некоторые недостатки, если вы используете БД с ограничением на количество соединений, которое превзойдено постоянными соединениями. Если ваша БД имеет лимит в 16 одновременных соединений и, при работающей сессии сервера, 17 дочерних потоков пытаются соединиться, один из них не сможет это сделать. Если в скриптах есть ошибки, которые не позволяют отключать соединения (такие как бесконечные циклы), БД с лишь 32 соединениями может быть быстро перегружена. Проверьте в документации к вашей БД информацию об обработке оставленных и незанятых соединений.

Предупреждение!

При использовании постоянных соединений необходимо помнить также ещё две вещи.
Первое - при использовании блокировки таблицы при постоянном соединении, если скрипт по каким-то причинам не может освободить блокировку, последующие скрипты, использующие то же самое соединение, будут блокированы бесконечно долго и могут потребовать рестарта httpd-сервера или сервера БД.
Второе - что, при использовании транзакций, блок транзакции также будет перенесён в следующий скрипт, использующий это соединение, если выполнение скрипта заканчивается до окончания выполнения блока транзакции. В этом случае вы можете использовать register_shutdown_function() для регистрации простой функции зачистки для разблокирования ваших таблиц или отката ваших транзакций. Ещё лучше избежать этих проблем полностью, не используя постоянные соединения в скриптах, где используются блокировка таблиц или транзакции (вы всё ещё можете использовать их в других местах).

Важное резюме. Постоянные соединения были созданы для отображения один-в-один регулярных соединений. Это значит, что вы должны всегда иметь возможность заменить постоянное соединение на не-постоянное, и это не должно изменить поведение вашего скрипта. Это может (и, возможно, будет) изменять эффективность работы скрипта, но не его поведение!

См. также 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().