Instrução BEGIN ... END

A instrução BEGIN ... END fornece às instruções definidas nas palavras-chave BEGIN e END o status de uma instrução única.

Isso permite que as instruções contidas:
  • Sejam o corpo de uma função ou um procedimento.
  • Tenham suas exceções manipuladas por uma rotina de tratamento.
  • Tenham suas execuções descontinuadas por uma instrução LEAVE.

SINTAXE

O segundo Label poderá estar presente apenas se o primeiro Label estiver presente. Se ambos os rótulos estiverem presentes, eles deverão ser idênticos. Duas ou mais instruções rotuladas no mesmo nível podem ter o mesmo rótulo, mas isso nega parcialmente a vantagem do segundo rótulo. A vantagem é que os rótulos correspondem a cada END com o seu BEGIN de maneira não ambígua e precisa. No entanto, uma instrução rotulada aninhada em Instruções não pode ter o mesmo rótulo, porque isso torna ambíguo o comportamento das instruções ITERATE e LEAVE.

Escopo de Variáveis

Um novo escopo de variável local é aberto imediatamente após a abertura de BEGIN e, portanto, quaisquer variáveis declaradas nesta instrução ficam fora de escopo quando é alcançado o END de finalização. Se uma variável local tiver o mesmo nome que uma variável existente, quaisquer referências a esse nome, que ocorrem após a instrução, acessam a variável local. Por exemplo:
DECLARE Variable1 CHAR 'Existing variable';

-- A reference to Variable1 here returns 'Existing variable'

  BEGIN
  -- A reference to Variable1 here returns 'Existing variable'

    DECLARE Variable1 CHAR 'Local variable';  -- Perfectly legal even though
the name is the same

    -- A reference to Variable1 here returns 'Local variable'
  END;

ATOMIC

Se ATOMIC for especificado, apenas uma instância de um fluxo de mensagens (ou seja, um encadeamento) terá permissão para executar as instruções de uma instrução específica BEGIN ATOMIC... END (identificada por seu esquema e rótulo), a qualquer momento. Se nenhum rótulo estiver presente, o comportamento será como se um rótulo de comprimento zero tivesse sido especificado.

A construção BEGIN ATOMIC é útil quando várias alterações precisam ser feitas em uma variável compartilhada e é importante evitar que outras instâncias vejam os estados intermediários dos dados. Considere o exemplo de código a seguir:
CREATE PROCEDURE WtiteSharedVariable1(IN NewValue CHARACTER)
SharedVariableMutex1 : BEGIN ATOMIC
  -- Configurar novo valor para a variável compartilhada
      END;

CREATE FUNCTION ReadSharedVariable1() RETURNS CHARACTER
SharedVariableMutex1 : BEGIN ATOMIC
  DECLARE Value CHARACTER;
  -- Obter valor de variável compartilhada
  RETURN Value;
  END;
O último exemplo assume que o procedimento WriteSharedVariable1 e a função ReadSharedVariable1 estão no mesmo esquema e são utilizados pelos nós no mesmo fluxo. Entretanto, não importa se o procedimento e a função estão, ou não, contidos em módulos ou se são utilizados em nós iguais ou diferentes. O intermediário assegura que, em um determinado momento, apenas um encadeamento esteja executando uma das instruções nas seções atômicas. Isso assegura que, por exemplo, duas gravações simultâneas ou uma leitura e um gravação simultâneas sejam executadas serialmente. Observe que:
  • A serialização é limitada ao fluxo. Dois fluxos que utilizam instruções BEGIN ATOMIC... END com o mesmo esquema e rótulo podem ser executados simultaneamente. Quanto a isso, várias instâncias em um fluxo e várias cópias de um fluxo não são equivalentes.
  • A serialização é limitada pelo esquema e rótulo. Instruções atômicas BEGIN ... END especificadas em esquemas diferentes ou com rótulos diferentes não interagem umas com as outras.
Nota: Você pode considerar isso de um modo diferente, se preferir. Para cada combinação de fluxo de mensagens, esquema e rótulo, o intermediário possui um mutex que impede o acesso simultâneo às instruções associadas a esse mutex.

Não aninhe instruções BEGIN ATOMIC... END, direta ou indiretamente, porque isso pode levar a "impasses". Por esse motivo, não utilize uma instrução PROPAGATE a partir de um bloco atômico.

Não é necessário utilizar a construção BEGIN ATOMIC em fluxos que nunca serão implementados com mais de uma instância (mas não convém arriscar). Também é desnecessário utilizar a construção BEGIN ATOMIC em leituras e gravações para variáveis compartilhadas. O intermediário sempre grava seguramente um novo valor em, e lê seguramente o valor mais recente de, uma variável compartilhada. ATOMIC é requerido apenas quando o aplicativo está suscetível à visualização de resultados intermediários.

Considere o seguinte exemplo:
DECLARE LastOrderDate SHARED DATE;
...
SET LastOrderDate = CURRENT_DATE;
...
SET OutputRoot.XMLNSC.Data.Orders.Order[1].Date = LastOrderDate;
Aqui, suponha que um encadeamento esteja atualizando periodicamente um LastOrderDate e um outro o esteja lendo periodicamente. Não há necessidade de utilizar ATOMIC, porque a segunda instrução SET sempre lê um valor válido. Se a atualização e a leitura ocorrerem em tempos muito próximos, não é possível determinar se será lido o valor novo ou antigo, mas é sempre um ou outro. O resultado nunca será constituído de lixo.
Mas agora considere o seguinte exemplo:
DECLARE Count SHARED INT;
...
SET Count = Count + 1;
Aqui, suponha que vários encadeamentos estejam executando periodicamente a instrução SET. Neste caso, é necessário utilizar ATOMIC, porque dois encadeamentos podem ler Count quase no mesmo instante e obter o mesmo valor. Ambos os encadeamentos desempenham a inclusão e ambos armazenam o mesmo valor novamente. O resultado final é, portanto, N+1 e não N+2.

O intermediário não fornece automaticamente travamento de nível mais alto que este (por exemplo, travamento abrangendo a instrução SET inteira), porque esse travamento é responsável por causar "impasses".

Dica

Você pode considerar a instrução BEGIN ... END como sendo uma construção em loop, que sempre entra em loop apenas uma vez. O efeito de uma instrução ITERATE ou LEAVE aninhada em uma instrução BEGIN ... END é, neste caso, conforme o esperado: o controle é transferido para a instrução após END. Utilizar ITERATE ou LEAVE em uma instrução BEGIN ... END é útil nos casos em que existe uma longa série de cálculos que precisam ser abandonados, porque um resultado limitado foi alcançado ou porque ocorreu um erro.

Conceitos relacionados
Visão Geral do ESQL
Tarefas relacionadas
Desenvolvendo ESQL
Referências relacionadas
Diagramas de Sintaxe: Tipos Disponíveis
instruções ESQL
Avisos | Marcas Registradas | Downloads | Biblioteca | Suporte | Feedback
Direitos Autorais IBM Corporation 1999, 2006 Última Atualização: 1 Sep 2006
ak04940_