Постійні з'єднання з базами даних
Постійні з'єднання є зв'язками з базами даних, які не закриваються при завершенні скрипту. При отриманні запиту на постійне з'єднання PHP спочатку перевіряє, чи є ідентичне постійне з'єднання (яке було відкрито під час попередніх звернень) і, якщо таке було знайдено, використовує його. Якщо ідентичного з'єднання немає, PHP створює нове. Під "ідентичним" мається на увазі з'єднання, відкрите на тому ж хості з таким же ім'ям користувача та паролем (якщо вони вказані).
Частина розробників, яка не має чіткого уявлення про те, як працює веб-сервер і як розподіляється навантаження, можуть отримати помилкове уявлення про те, чим насправді є постійні з'єднання. Зокрема, постійні з'єднання не надають можливість відкривати 'Сесії користувача' в тому ж самому з'єднанні, вони не надають можливість організовувати ефективніші транзакції, також вони не надають безліч інших корисних можливостей. Фактично, постійні з'єднання не надають ніякий функціональності, яка була б неможлива у непостійних аналогічних сполуках.
Чому?
Це залежить від того, як відбувається взаємодія з веб-сервером. Існує три основні способи використання PHP сервером для створення веб-сторінок.
Перший спосіб полягає в тому, щоб використовувати PHP як CGI-обертку. При цьому PHP-інтерпретатор створюється і знищується при кожному зверненні до сторінки (PHP-скрипт). Оскільки інтерпретатор знищується після кожного запиту до сервера, всі ресурси, що використовуються (у тому числі і з'єднання з базою даних) закриваються. Отже, у цьому випадку ви не отримаєте нічого від використання постійних з'єднань – їх просто нема.
Другий і найбільш популярний спосіб - використовувати PHP як модуль в сервері, який використовує кілька процесів. До таких серверів зараз входить тільки Apache. У такому разі можна виділити один процес (батьківський), який координує роботу всіх інших процесів (дочірніх), які фактично і виконують роботу з обслуговування веб-сторінок. При кожному зверненні клієнта до сервера запит перенаправляється одному з дочірніх процесів, який зараз не зайнятий обслуговуванням іншого клієнта. Це означає, що коли той же клієнт виконує повторний запит до сервера, він може бути оброблений іншим дочірнім процесом, відмінним від того, який був при першому зверненні. Після відкриття постійного з'єднання кожна наступна сторінка, що вимагає з'єднання з базою даних, може використовувати вже встановлене з'єднання з SQL-сервером.
Третій спосіб - використовувати PHP як плагін у багатопоточному веб-сервері. В даний час в PHP реалізована підтримка ISAPI, WSAPI, і NSAPI (для Windows-платформ), які дозволяють підключати PHP до таких багатопоточних серверів, як Netscape FastTrack (iPlanet), Microsoft Internet Information Server (IIS) і O'Reilly WebSite Pro. У цьому випадку поведінка PHP повністю аналогічна до розглянутої раніше моделі з використанням декількох процесів.
Якщо постійні з'єднання не надають ніякої додаткової функціональності, чим вони тоді такі хороші?
Відповідь міститься у підвищенні ефективності. Постійні з'єднання корисні в тому випадку, якщо при відкритті великої кількості SQL-з'єднань виникає відчутне навантаження на сервер. Те, наскільки велике це навантаження, залежить від багатьох факторів. Наприклад, від того, яка саме база даних використовується, чи знаходиться вона на тому ж комп'ютері, що і ваш веб-сервер, наскільки завантажена машина, на якій встановлений SQL-сервер, і так далі. Якщо витрати на встановлення з'єднання великі, постійні з'єднання можуть вам суттєво допомогти. Вони дозволяють дочірньому процесу протягом усього життєвого циклу використовувати те саме з'єднання замість того, щоб створювати його при обробці кожної сторінки, яка взаємодіє з SQL-сервером. Це означає, що кожен дочірній процес, який відкрив постійне з'єднання, матиме власне з'єднання з сервером. Наприклад, якщо у вас запущено 20 дочірніх процесів, які виконали скрипт, який використовував постійне з'єднання з SQL-сервером, ви отримаєте 20 різних з'єднань з SQL-сервером, по одному на кожен дочірній процес.
Слід зауважити, що цей підхід має деякі недоліки: якщо ви використовуєте базу даних з обмеженою кількістю можливих підключень, воно може бути перевищено кількістю постійних з'єднань, що запитуються дочірніми процесами. Наприклад, якщо ваша база даних дозволяє 16 одночасних з'єднань, і під час навантаження на сервер 17 дочірніх процесів спробують відкрити з'єднання, одна зі спроб зазнає невдачі. Якщо у вашому коді містяться помилки, що не дозволяють закривати з'єднання (наприклад, нескінченні цикли), база даних з 32 одночасними підключеннями незабаром може виявитися заблокованою. Інформацію про те, як обробляти відкриті та не використовувані з'єднання, ви можете знайти в документації до бази даних.
Увага
Є ще два додаткові застереження, які слід пам'ятати під час роботи з постійними з'єднаннями. У випадку, якщо скрипт блокує таблицю і з яких-небудь причин не може її звільнити, при використанні постійного з'єднання всі наступні скрипти, які використовують це з'єднання, будуть нескінченно блоковані і можуть вимагати рестарту веб-сервера або сервера баз даних. Друге застереження полягає в тому, що відкриті транзакції, якщо вони не були закриті до завершення роботи скрипта, будуть продовжені в наступному скрипті, що використовує це постійне з'єднання. Виходячи з цього, ви можете використати функцію register_shutdown_function() для вказівки простої функції, яка знімає блокування таблиць або відкату транзакцій. Ще краще уникнути цих проблем повністю, не використовуючи постійні з'єднання в скриптах, які використовують блокування таблиць або транзакції (при цьому ви все ще можете їх використовувати десь в іншому місці).
Важливе резюме. Постійні з'єднання були створені для точного відображення звичайних з'єднань. Це означає, що у вас завжди є можливість замінити всі постійні з'єднання непостійними, і це ніяк не вплине на поведінку скрипта. Така заміна може вплинути (і, мабуть, вплине) на ефективність роботи скрипта, але не на його поведінку.
Смотрите такжеibase_pconnect() ociplogon() odbc_pconnect() oci_pconnect() pfsockopen() і pg_pconnect()