지속적인 접속은 스크립트 수행이 종료되어도 연결을 끊지 않는 접속을 말한다. 지속적인 접속이 요청되면, PHP는 기존의 (이전에 열어 두었던) 동일한(identical) 지속적인 접속이 있는지 검사한다. 만약 있다면 기존의 것을 사용하고, 없다면 새로운 연결을 생성한다. '동일한' 접속이란 같은 호스트에 같은 사용자명과 같은 암호를 사용하여 열린 접속을 말한다.
가끔 웹서버의 작동과 작업의 할당에 대해 잘 알고 있지 못하는 사람들은 지속적인 접속이 사실은 별 것 아니라고 오해하기도 한다. 특히, 지속적인 접속이 동일한 연결에서 'user sessions'를 여는데 별 나을 것도 없다라던가, transaction을 효율적으로 처리하는 것도 아니다라던가, 혹은 다른 어떤 특별한 것을 하는 것도 아니라고 한다. 사실, 이런 말들에 대해 명백히 말하자면, 지속적인 접속은 비지속적인 접속에 비해 어떠한 기능적인 향상도 주지 못한다.
왜?
이것은 웹서버의 동작 방식에 따라 다른 효과를 낸다. 여러분의 웹서버가 웹 페이지를 만들기위해 PHP를 이용하는데는 3가지 방법이 있다.
첫 번째 방법은 PHP를 CGI "래퍼(wrapper)"의 형태로 사용하는 것이다. 이 방법의 경우, 웹서버에 매 PHP 페이지가 요구될 때 마다, PHP 인터프리터의 실행이 만들어지고 사리진다. 따라서 매 요구가 종료될 때마다 인터프리터의 실행이 종료되므로, 실행 중 만들었던(SQL 연결를 포함) 모든 자원은 실행 종료와 함께 해제된다. 이 경우 지속적인 접속을 사용하여 어떤 이득도 얻을 수 없다. 다르게 말하면 이 경우는 지속적인 접속을 해도 지속적이지 않다.
두 번째 방법은 가장 대중적인 방법인데, PHP를 다중프로세스 웹서버의 모듈로 사용하는 것이다. (현재는 아파치가 유일하다) 다중프로세스 서버는 보통 한 개의 부모 프로세스와, 이와 유기적으로 연결되어 웹 페이지를 실제로 만드는 작업을 하는 여러개의 자식 프로세스들을 가지고 있다. 클라이언트에서 요청이 왔을 때, 다른 클라이언트를 처리하고 있지 않은 자식 프로레스로 넘겨집니다. 이는 동일한 클라이언트가 서버에 두번째 요청을 하였을 때, 처음과 다른 자식 프로세스에서 처리할 수 있다는 의미입니다. 지속적인 접속을 열면, SQL 서비스를 요구하는 모든 페이지에서 동일한 SQL 서버 접속을 재사용할 수 있습니다.
마지막 방법은 PHP를 멀티쓰레드 웹서버의 플러그인 형태로 작동시키는 것이다. 현재 PHP4는 윈도우 환경에서 ISAPI 혹은 WSAPI, NSAPI의 방법을 사용하여 Netscape FastTrack, Microsoft's Internet Information Server (IIS), O'Reilly's WebSite Pro 등의 멀티쓰레드 웹서버에서 플러그인으로 동작한다. 이 동작은 앞에서 설명한 다중프로세스 모델과 동일합니다.
지속적인 접속이 실제로 어떠한 기능적인 향상도 주지 못한다면, 이것을 사용해 어떤 이점이 있나요?
이것에 대한 간단한 답은 효율성이다. 지속적인 접속은 SQL 서버와의 연결을 만드는 것에 따른 overhead가 클 경우에 유용하다. 이 overhead는 많은 요인에 따라 커지기도 하고 작아지기도 한다. 어떤 종류의 데이터베이스인가? 웹서버와 같은 컴퓨터에 데이터베이스 서버가 있는가? SQL 서버가 어떻게 사용되고 있는가? 등에 따라 크게 달라진다. 접속에 따른 overhead가 클 경우에 지속적인 접속은 적지 않은 도움을 줄 것이다. 이것은 자식 process에서 SQL 서버에 접속을 요청할 때 마다 접속을 만드는 대신, 이 프로세스가 종료될 때 까지 살아있는 한 개의 접속 만을 사용한다. 이것은 모든 지속적인 접속을 사용한 프로세스는, 그에 해당하는 한 개의 지속적인 접속을 가지고 있다는 것을 의미한다. 예를 들어 SQL 서버에 대하여 지속적인 접속을 사용하는 스크립트를 실행하였던 20개의 다른 자식 프로세스가 있다면, 아마도 각각의 자식 프로세스에 대해 1개씩, 20개의 SQL 접속이 있을 것이다.
이 방법은 지속적인 접속의 개수가 데이타베이스 서버가 허용하는 접속수를 초과해서 설정되어 있는 경우 문제가 될 수 있다. 만약 데이타베이스가 16개의 동시 접속을 허용하고, 이 서버 세션들이 모두 사용중이면, 17번째 thread는 연결을 시도하다가 실패할 것이다. 만약 여러분이 만든 스크립트에 이런 경우에 대비한 특별한 대책이 없이 재시도를 반복하다보면 가능한 모든 connection을 사용하여 복구할 수 없게 된다. 이런 abandoned 혹은 idle connection을 다루는 자세한 설명은 데이타베이스 문서를 참조하기 바란다.
지속적인 접속을 사용할때 두가지 추가적인 경고를 염두에 두고 있어야 한다 한가지는 지속적인 접속에서 테이블 락킹(locking)을 사용할때이다. 스크립트가 어떤 이유로 락을 풀수 없을때, 같은 접속을 사용하는 다음 스크립트는 무한정 block될것이고 이 경우에는 httpd 서버나 데이터베이스 서버를 재시작시켜야 할수도 있다. 다른 한가지는 트랜잭션을 사용할때이다. 트랜잭션 블록은 그 트랜잭션 블록이 수행되기 전에 스크립트가 수행을 종료하면 그 접속을 사용하는 다음 스크립트에 이월하게 된다. 각각의 경우에, register_shutdown_function()을 사용하여 테이블 unlock하거나 트랜잭션을 롤백하는 해제 함수를 등록 할수 있다. 이런 문제를 완전히 회피하기 위한 더 좋은 방법은 지속적인 접속을 사용하는 스크립트에서 테이블 락이나 트랜젝션을 사용하지 않는 것이다 (어느 곳에서는 그것을 사용할수 있다)
중요한 언급 한가지! 지속적인 접속은 일반적인 접속에 일대일로 대응되도록 설계되었다. 이것은 스크립트의 다른 부분은 그대로 두고, 언제라도 비지속적인 접속을 지속적인 접속으로 대치할 수 있다는 것을 의미한다. 이기능으로 아마도 스크립트의 동작이 아니라 효율을 향상시킬 수도 있을 것이다.
fbsql_pconnect(), ibase_pconnect(), ifx_pconnect(), ingres_pconnect(), msql_pconnect(), mssql_pconnect(), mysql_pconnect(), ociplogon(), odbc_pconnect(), oci_pconnect(), pfsockopen(), pg_pconnect(), sybase_pconnect() 참고.