Files
2025-01-05 14:05:49 -03:00

371 lines
13 KiB
XML
Executable File
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?xml version="1.0" encoding="utf-8"?>
<!-- EN-Revision: f4c44b86948f70a7e89f582b500e2595452e00f0 Maintainer: leonardolara Status: ready -->
<chapter xml:id="oci8.taf" xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>Suporte ao OCI8 Transparent Application Failover (TAF)</title>
<para>
TAF é um recurso do Oracle Database que fornece alta disponibilidade.
Ele permite que apliações PHP OCI8 se reconectem automaticamente a um
banco de dados pré-configurado quando a conectividade do banco de dados falha devido a
uma falha na instância ou na rede.
</para>
<para>
Em um sistema Oracle Database configurado, o TAF ocorre quando a aplicação
PHP detecta que a instância do banco de dados está inativa
ou inacessível. Ele estabelece uma conexão com outro nó em uma
configuração Oracle <link xlink:href="&url.oracle.taf.rac;">RAC</link>,
em um banco de dados hot standby ou na própria instância
de banco
de dados. Consulte o <link xlink:href="&url.oracle.taf.ociguide;">Guia
do programador da Interface de Chamada Oracle</link> para obter mais informações sobre
o OCI TAF.
</para>
<para>
Um retorno de chamada de aplicação pode ser registrado
com <function>oci_register_taf_callback</function>. Durante a recuperação
da falha, o processamento normal da aplicação é interrompido e o retorno de chamada
registrado é invocado. O retorno de chamada notifica a aplicação sobre os
eventos de falha. Se a recuperação for bem-sucedida, o processamento normal
será retomado. Se a recuperação abortar, quaisquer operações de banco de dados seguintes
na aplicação falharão devido à falta de conexão
disponível.
</para>
<para>
Quando uma conexão se recupera para um outro banco de dados, o retorno de chamada pode
redefinir qualquer estado de conexão necessário, por exemplo, reproduzindo quaisquer
comandos ALTER SESSION necessários se o serviço de banco de dados não tiver
-failover_restore ativado.
</para>
<para>
Um retorno de chamada de aplicação pode ser removido chamando <function>oci_unregister_taf_callback</function>.
</para>
<section>
<title>Configurando o Transparent Application Failover</title>
<para>
O TAF pode ser configurado no lado do PHP OCI8 ou na configuração
do banco de dados. Se ambos estiverem configurados, as configurações do lado do banco de dados
terão precedência.
</para>
<para>
Configure o TAF no PHP OCI8 (no lado do cliente) incluindo o
parâmetro FAILOVER_MODE na parte CONNECT_DATA de um
descritor de conexão. Consulte Configurando o Transparent Application
Failover no <link xlink:href="&url.oracle.taf.clientconfig;">Guia
do Administrador de Serviços de Rede do Oracle Database</link> para
obter mais informações sobre a configuração do lado do cliente do TAF.
</para>
<para>
Um exemplo de tnsnames.ora para configurar o TAF para reconexão à
mesma instância do banco de dados:
</para>
<para>
<informalexample>
<screen>
<![CDATA[
ORCL =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = 127.0.0.1)(PORT = 1521))
(CONNECT_DATA =
(SERVICE_NAME = orclpdb1)
(FAILOVER_MODE =
(TYPE = SELECT)
(METHOD = BASIC)
(RETRIES = 20)
(DELAY = 15))))
]]>
</screen>
</informalexample>
</para>
<para>
Como alternativa, configure o TAF no lado do banco de dados
modificando o serviço de destino com
<link xlink:href="&url.oracle.taf.srvctl;">srvctl</link>
(para RAC) ou o procedimento empacotado
<link xlink:href="&url.oracle.taf.dbmsservice;">DBMS_SERVICE.MODIFY_SERVICE</link> (para
bancos de dados de instância
única).
</para>
</section>
<section>
<title>Usando Chamada de Retorno TAF no OCI8</title>
<para>
Uma chamada de retorno TAF é uma função de aplicação que pode ser
registrada para ser chamada durante a recuperação de falha. Ela é chamada
diversas vezes ao restabelecer a conexão da aplicação.
</para>
<para>
A chamada de retorno ocorre primeiro quando uma perda de conexão é detectada.
Isso permite que a aplicação atue de acordo com o atraso
futuro da recuperação. Se a recuperação for bem-sucedida,
a chamada de retorno será invocada depois que a conexão for restabelecida
e utilizável. Neste momento, a aplicação pode ressincronizar
as configurações da sessão e executar ações como informar ao usuário
que ocorreu uma recuperação. Se ela não for bem-sucedida, ocorrerá
uma chamada de retorno para informar à aplicação que a recuperação não
ocorreu e que a conexão está inutilizável.
</para>
<para>
A interface de uma função de retorno TAF definida pelo usuário é
a seguinte:
</para>
<methodsynopsis>
<type>int</type><methodname>userCallbackFn</methodname>
<methodparam><type>resource</type><parameter>connection</parameter></methodparam>
<methodparam><type>int</type><parameter>event</parameter></methodparam>
<methodparam><type>int</type><parameter>type</parameter></methodparam>
</methodsynopsis>
<para>
<variablelist>
<varlistentry>
<term><parameter>connection</parameter></term>
<listitem>
<para>
A conexão Oracle na qual a chamada de retorno TAF foi
registrada por meio de <function>oci_register_taf_callback</function>.
A conexão não é válida até que a
recuperação seja concluída com êxito.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><parameter>event</parameter></term>
<listitem>
<para>
O evento de recuperação indica o status atual da
recuperação.
</para>
<para>
<itemizedlist>
<listitem>
<para>
<constant>OCI_FO_BEGIN</constant> indica que
a recuperação detectou uma conexão perdida e a recuperação
está iniciando.
</para>
</listitem>
<listitem>
<para>
<constant>OCI_FO_END</constant> indica conclusão
de recuperação com sucesso.
</para>
</listitem>
<listitem>
<para>
<constant>OCI_FO_ABORT</constant> indica que
a recuperação não foi bem-sucedida e que não há opção
de uma nova tentativa.
</para>
</listitem>
<listitem>
<para>
<constant>OCI_FO_ERROR</constant> também indica
que a recuperação não foi bem-sucedida mas dá à
aplicação a oportunidade de lidar com o erro
e retornar OCI_FO_RETRY para tentar a recuperação novamente.
</para>
</listitem>
<listitem>
<para>
<constant>OCI_FO_REAUTH</constant> indica
que um usuário Oracle foi re-autenticado.
</para>
</listitem>
</itemizedlist>
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><parameter>type</parameter></term>
<listitem>
<para>
O tipo da recuperação. Isto permite que a função de retorno saiba que
tipo de recuperação a aplicação solicitou. Os
valores usuais são os seguintes:
</para>
<para>
<itemizedlist>
<listitem>
<para>
<constant>OCI_FO_SESSION</constant> indica que
o usuário solicitou recuperação apenas de sessão. Por
exemplo, se uma conexão de usuário é perdida, uma
nova sessão é automaticamente criada para o usuário
no backup. Este tipo de recuparação não tenta
recuperar SELECTs.
</para>
</listitem>
<listitem>
<para>
<constant>OCI_FO_SELECT</constant> indica que
o usuário também solicitou recuperação SELECT.
Isto permite que usuários com cursores abertos continuem
buscando dados após a falha.
</para>
</listitem>
</itemizedlist>
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><parameter>return value</parameter></term>
<listitem>
<para>
<itemizedlist>
<listitem>
<para>
<literal>0</literal> indica que os passos de
recuperação devem continuar normalmente.
</para>
</listitem>
<listitem>
<para>
<constant>OCI_FO_RETRY</constant> indica que
a recuperação deve ser tentada novamente pelo Oracle.
No caso de um erro durante a recuperação para uma nova
conexão, o TAF poderá tentar novamente a recuperação.
Normalmente, o código da aplicação deve ficar inativo por
um tempo antes de retornar OCI_FO_RETRY.
</para>
</listitem>
</itemizedlist>
</para>
</listitem>
</varlistentry>
</variablelist>
</para>
<example>
<title>Registrando uma chamada de retorno TAF</title>
<programlisting role="php">
<![CDATA[
<?php
// Define chamda de retorno no espaço de usuário
class MyClass {
public static $retry_count;
public static function TAFCallback($conn, $event, $type)
{
switch ($event) {
case OCI_FO_BEGIN:
printf(" Recuperando ... Por favor aguarde\n");
printf(" Tipo de recuperação é %s \n",
(($type==OCI_FO_SESSION) ? "SESSION"
:(($type==OCI_FO_SELECT) ? "SELECT" : "DESCONHECIDA!")));
self::$retry_count = 0;
break;
case OCI_FO_ABORT:
// A aplicação não pode continuar usando o banco de dados
printf(" Recuperação abortada. Recuperação não irá ocorrer.\n");
break;
case OCI_FO_END:
// Recuperação conclui com sucesso. Informa usuários que uma recuperação aconteceu.
printf(" Recuperação concluída ... retomando os serviços\n");
break;
case OCI_FO_REAUTH:
printf(" Recuperando usuário ... retomando os serviços\n");
// Reproduz qualquer comando ALTER SESSION associados com esta conexão
// por exemplo, oci_parse($conn, ALTER SESSION …’) ;
break;
case OCI_FO_ERROR:
// Para de tentar se já foram feitas 20 tentativas.
if (self::$retry_count >= 20)
return 0;
printf(" Erro de recuperação recebido. Aguardando...\n");
sleep(10);
self::$retry_count++;
return OCI_FO_RETRY; // tenta a recuperação novamente
break;
default:
printf("Evento de recuperação desconhecido: %d.\n", $event);
break;
}
return 0;
}
}
$fn_name = 'MyClass::TAFCallback';
$conn = oci_connect('hr', 'welcome', 'orcl');
$sysconn = oci_connect('system', 'oracle', 'orcl');
// Usa uma conexão privilegiada para construir uma instrução SQL que iniciará a recuperação
$sql = <<< 'END'
select unique 'alter system disconnect session '''||sid||','||serial#||''''
from v$session_connect_info
where sid = sys_context('USERENV', 'SID')
END;
$s = oci_parse($conn, $sql);
oci_execute($s);
$r = oci_fetch_array($s);
$disconnectssql = $r[0];
oci_register_taf_callback($conn, $fn_name); // Registra TAFCallback para Oracle TAF
print "Analisando a consulta do usuário\n";
$sql = "select systimestamp from dual";
$stmt = oci_parse($conn, $sql);
// Por exemplo, se ocorrer uma perda de conexão neste ponto, oci_execute() detectará
// a perda e a recuperação será iniciada. Durante a recuperação, oci_execute() invocará
// a função de retorno de chamada do TAF diversas vezes. Se a recuperação for bem-sucedida,
// uma nova conexão será criada de forma transparente e oci_execute() continuará
// normalmente. As configurações da sessão de conexão podem ser redefinidas na função de
// retorno de chamada TAF. Se a recuperação for abortada, oci_execute() retornará um erro
// porque uma conexão válida não está disponível.
// Desconecta o usuário, o que inicia a recuperação
print "Desconectando o usuário\n";
$discsql = oci_parse($sysconn, $disconnectssql);
oci_execute($discsql);
print "Executando a consulta do usuário\n";
$e = oci_execute($stmt);
if (!$e) {
$m = oci_error($stmt);
trigger_error("Não foi possível executar a instrução: ". $m['message'], E_USER_ERROR);
}
$row = oci_fetch_array($stmt);
print $row[0] . "\n";
// executa outras instruções SQL com a nova conexão, se ainda for válida
// $stmt = oci_parse($conn, . . .);
?>
]]>
</programlisting>
</example>
</section>
<section>
&reftitle.seealso;
<simplelist>
<member><function>oci_register_taf_callback</function></member>
<member><function>oci_unregister_taf_callback</function></member>
</simplelist>
</section>
</chapter>
<!-- Keep this comment at the end of the file
Local variables:
mode: sgml
sgml-omittag:t
sgml-shorttag:t
sgml-minimize-attributes:nil
sgml-always-quote-attributes:t
sgml-indent-step:1
sgml-indent-data:t
indent-tabs-mode:nil
sgml-parent-document:nil
sgml-default-dtd-file:"~/.phpdoc/manual.ced"
sgml-exposed-tags:nil
sgml-local-catalogs:nil
sgml-local-ecat-files:nil
End:
vim600: syn=xml fen fdm=syntax fdl=2 si
vim: et tw=78 syn=sgml
vi: ts=1 sw=1
-->