<?php
include_once $_SERVER['DOCUMENT_ROOT'] . '/include/shared-manual.inc';
$TOC = array();
$TOC_DEPRECATED = array();
$PARENTS = array();
include_once dirname(__FILE__) ."/toc/features.inc";
$setup = array (
  'home' => 
  array (
    0 => 'index.php',
    1 => 'PHP Manual',
  ),
  'head' => 
  array (
    0 => 'UTF-8',
    1 => 'pt_BR',
  ),
  'this' => 
  array (
    0 => 'features.persistent-connections.php',
    1 => 'Conex&otilde;es Persistentes com o Banco de Dados',
    2 => 'Conex&otilde;es Persistentes com o Banco de Dados',
  ),
  'up' => 
  array (
    0 => 'features.php',
    1 => 'Caracter&iacute;sticas',
  ),
  'prev' => 
  array (
    0 => 'features.connection-handling.php',
    1 => 'Tratamento de Conex&otilde;es',
  ),
  'next' => 
  array (
    0 => 'features.commandline.php',
    1 => 'Uso da linha de Comando',
  ),
  'alternatives' => 
  array (
  ),
  'source' => 
  array (
    'lang' => 'pt_BR',
    'path' => 'features/persistent-connections.xml',
  ),
  'history' => 
  array (
  ),
);
$setup["toc"] = $TOC;
$setup["toc_deprecated"] = $TOC_DEPRECATED;
$setup["parents"] = $PARENTS;
manual_setup($setup);

contributors($setup);

?>
<div id="features.persistent-connections" class="chapter">
 <h1 class="title">Conexões Persistentes com o Banco de Dados</h1>


 <div class="simplesect">
  <h3 class="title">O que são Conexões Persistentes?</h3>
  <p class="simpara">
   Conexões persistentes são conexões que não fecham quando a
   execução do script termina. Quando uma conexão persistente é
   requisitada, o PHP verifica se uma conexão persistente
   idêntica (que foi mantida aberta anteriormente) já existe; se existir,
   ela é reutilizada, senão, uma nova conexão é criada. Uma conexão
   &#039;idêntica&#039; é uma aberta para o mesmo host com o
   mesmo nome de usuário e a mesma senha (onde for aplicável).
  </p>
  <p class="simpara">
   Não há nenhuma maneira de solicitar uma conexão específica ou de garantir
   que a conexão retornada sera uma existente ou uma
   nova (se todas as conexões existentes estiverem em uso ou se a solicitação estiver sendo
   atendida por um trabalhador diferente, que tem um conjunto separado de conexões).
  </p>
  <p class="simpara">
   Portanto, conexões persistentes do PHP não podem ser usadas para, por exemplo:
  </p>
  <ul class="simplelist">
   <li>atribuir uma sessão de banco de dados específica a um usuário da web específico</li>
   <li>criar uma grande transação em várias solicitações</li>
   <li>iniciar uma consulta em uma solicitação e coletar os resultados em outra</li>
  </ul>
  <p class="simpara">
   Conexões persistentes não fornecem <em>nenhuma</em>
   funcionalidade que não seria possível com conexões não persistentes.
  </p>
 </div>

 <div class="simplesect" id="persistent-connections.web">
  <h3 class="title">Solicitações da Web</h3>
  <p class="simpara">
   Existem duas maneiras pelas quais um servidor web pode utilizar o PHP para gerar
   páginas web:
  </p>
  <p class="simpara">
   O primeiro método é usar o PHP como um CGI &quot;wrapper&quot;. Quando executado dessa
   maneira, uma instância do interpretador do PHP é criada e destruída
   para cada requisição de página (para uma página PHP) para o servidor web.
   Como ela é destruída após cada requisição, quaisquer recursos que ela
   adquirir (como uma conexão para um servidor de banco de dados SQL) são fechados quando
   ela é destruída. Nesse caso, não há ganho em
   usar conexões persistentes - elas simplesmente não persistem.
  </p>
  <p class="simpara">
   O segundo método, e o mais popular, é rodar o PHP-FPM ou o PHP como um módulo
   em um servidor web com multi-processos (atualmente somente o Apache).
   Essas configurações têm tipicamnente um processo (o pai) que
   coordena uma série de processos (seus filhos) que realmente fazem
   o trabalho de servir as páginas web. Quando uma requisição chega de um
   cliente, ela é entregue à um dos filhos que já não estiver
   servindo outro cliente. Isso significa que quando o mesmo cliente
   faz uma segunda requisição para o servidor, ele pode ser atendido por um processo
   filho diferente do que da primeira vez. Uma vez que uma conexão persistente tenha sido
   aberta, cada página subsequente servida pelo mesmo processo filho pode reutilizar a
   conexão já estabelecida ao servidor SQL.
  </p>
  <blockquote class="note"><p><strong class="note">Nota</strong>: 
   <p class="para">
    O método em uso pode ser consultado verificando o valor de
    &quot;Server API&quot; na saída de <span class="function"><a href="function.phpinfo.php" class="function">phpinfo()</a></span> ou o valor de
    <strong><code><a href="reserved.constants.php#constant.php-sapi">PHP_SAPI</a></code></strong>, executado a partir de uma solicitação web.
   </p>
   <p class="para">
    Se a API do Servidor for &quot;Apache 2 Handler&quot; ou &quot;FPM/FastCGI&quot;, as conexões
    persistentes serão usadas em todas as solicitações atendidas pelo mesmo trabalhador. Para qualquer
    outro valor, as conexões persistentes não persistirão após cada solicitação.
   </p>
  </p></blockquote>
 </div>

 <div class="simplesect" id="persistent-connections.cli">
  <h3 class="title">Command-line Processes</h3>
  <p class="simpara">
   Como a linha de comando PHP usa um novo processo para cada script, conexões persistentes
   não são compartilhadas entre scripts de linha de comando, portanto, não há
   nenhum valor em usá-las em scripts transitórios, como crons ou comandos.
   No entanto, elas podem ser úteis, por exemplo, em um servidor de aplicação de longa
   duração que atende a muitas solicitações ou tarefas, onde cada uma pode precisar
   de sua própria conexão com o banco de dados.
  </p>
 </div>

 <div class="simplesect" id="persistent-connections.why">
  <h3 class="title">Por que usá-las?</h3>
  <p class="simpara">
   Conexões persistentes são benéficas quando a sobrecarga para criar uma conexão ao
   servidor SQL é alta. Se essa sobrecarga é realmente significativa depende
   de vários fatores como o tipo de banco de dados, se reside na mesma
   máquina do servidor web e o quão carregada está a máquina. Quando
   a sobrecarga de conexão é alta, conexões persistentes podem ajudar consideravelmente:
   cada processo filho se conecta uma vez só durante toda sua duração, e não
   a cada vez que ele processa uma página que requer uma conexão ao servidor
   SQL. Isso significa que cada filho que abre uma conexão persistente
   manterá sua própria conexão persistente ao servidor. Por exemplo, se cada um de 20 processos
   filhos diferentes rodarem um script que faz uma conexão persistente ao servidor
   SQL, haverá 20 conexões separadas a esse servidor,
   uma de cada filho.
  </p>
 </div>

 <div class="simplesect" id="persistent-connections.drawbacks.conn-limits">
  <h3 class="title">Possíveis desvantagens: limites de conexão</h3>
  <p class="simpara">
   Perceba, no entanto, que isso pode ter desvantagens ao
   usar um banco de dados com limite de conexões que são excedidas pela conexões
   persistentes dos filhos. Se o banco de dados tem um limite de 16 conexões
   simultâneas e durante uma sessão movimentada do servidor 17 processos
   filhos tentarem se conectar, um deles falhará. Se houver
   bugs nos scripts que não permitem que as conexões se fechem
   (como loops infinitos), um banco de dados com apenas 16 conexões
   pode rapidamente ficar atolado.
  </p>
  <p class="simpara">
   Conexões persistentes geralmente aumentam o número de conexões abertas
   a qualquer momento, pois os trabalhadores ociosos ainda manterão as conexões
   para as solicitações anteriores. Se um grande número de trabalhadores for criado para
   lidar com um pico de solicitações, as conexões que eles abriram permanecerão até
   que o trabalhador seja encerrado ou que o servidor de banco de dados feche a conexão.
  </p>
  <p class="simpara">
   Certifique-se de que o número máximo de conexões permitidas pelo servidor de banco de dados
   seja maior que o número máximo de trabalhadores de solicitação da web (além de qualquer outro
   uso, como crons ou conexões administrativas).
  </p>
  <p class="simpara">
   Consulte a documentação do banco de dados para obter informações sobre como lidar com conexões abandonadas ou
   ociosas (tempo limite). Tempo limite longo pode aumentar significativamente o
   número de conexões persistentes abertas ao mesmo tempo.
  </p>
 </div>

 <div class="simplesect" id="persistent-connections.drawbacks.state">
  <h3 class="title">Possíveis desvantagens: manter o estado de conexão</h3>
  <p class="simpara">
   Algumas extensões de banco de dados realizam limpeza automática quando a conexão é
   reutilizada; outras deixam essa tarefa a critério do desenvolvedor da aplicação.
   Dependendo da extensão de banco de dados escolhida e do projeto da aplicação, a limpeza
   manual pode ser necessária antes da saída do script. Alterações que podem deixar
   conexões em um estado inesperado incluem:
  </p>
  <ul class="simplelist">
   <li>Banco de dados selecionado / padrão</li>
   <li>Bloqueio de tabelas</li>
   <li>Transações não confirmadas</li>
   <li>Tabelas temporárias</li>
   <li>Configurações ou recursos específicos de conexão, como perfilagem</li>
  </ul>
  <p class="simpara">
   Bloqueios de tabela e transações que não são limpos ou fechados podem fazer com que
   outras consultas sejam bloqueadas indefinidamente e/ou causar a reutilização subsequente
   da conexão, causando alterações inesperadas.
  </p>
  <p class="simpara">
   Selecionar o banco de dados errado fará com que a reutilização subsequente da
   conexão não consiga executar as consultas conforme o esperado (ou executá-las no
   banco de dados errado se os esquemas forem semelhantes o suficiente).
  </p>
  <p class="simpara">
   Se as tabelas temporárias não forem limpas, as solicitações subsequentes não conseguirão
   recriar a mesma tabela.
  </p>
  <p class="simpara">
   Pode-se implementar a limpeza usando destruidores de classe ou
   <span class="function"><a href="function.register-shutdown-function.php" class="function">register_shutdown_function()</a></span>. Podem ser considerados também
   proxies de grupo de conexão dedicados que incluam isso como parte de
   sua funcionalidade.
  </p>
 </div>

 <div class="simplesect" id="persistent-connections.final-words">
  <h3 class="title">Palavras Finais</h3>
  <p class="simpara">
   Considerando seu comportamento e as potenciais desvantagens descritas acima, não se deve
   usar conexões persistentes sem uma análise cuidadosa. Elas não devem ser
   usadas sem implementar alterações adicionais na aplicação ou sem um configuração cuidadosa
   do servidor de banco de dados e servidor web e/ou PHP-FPM.
  </p>
  <p class="simpara">
   Considere soluções alternativas, como investigar e corrigir as causas de
   sobrecargas na criação de conexões (por exemplo, desabilitando pesquisas reversas de DNS no
   servidor de banco de dados) ou proxies de grupo de conexões dedicados.
  </p>
  <p class="simpara">
   Para APIs da web de alto volume, considere usar tempos de execução alternativos ou servidores de
   aplicações de longa execução.
  </p>
 </div>

 <div class="simplesect" id="persistent-connections.seealso">
  <h3 class="title">Veja Também</h3>
  <ul class="simplelist">
   <li><span class="function"><a href="function.ibase-pconnect.php" class="function">ibase_pconnect()</a></span></li>
   <li><span class="function"><a href="function.oci-pconnect.php" class="function">oci_pconnect()</a></span></li>
   <li><span class="function"><a href="function.odbc-pconnect.php" class="function">odbc_pconnect()</a></span></li>
   <li><span class="function"><a href="function.pfsockopen.php" class="function">pfsockopen()</a></span></li>
   <li><span class="function"><a href="function.pg-connect.php" class="function">pg_connect()</a></span></li>
   <li><a href="mysqli.persistconns.php" class="link">MySQLi e Conexões Persistentes</a></li>
   <li><a href="pdo.connections.php" class="link">Gerenciamento de Conexões PDO</a></li>
  </ul>
 </div>
</div>
<?php manual_footer($setup); ?>