4D v14.3

Usar Transações

Página Inicial

 
4D v14.3
Usar Transações

Usar Transações  


 

 

As transações são uma serie de modificações realizadas no interior de um processo sobre dados relacionados. Uma transação não é guardada permanentemente no banco até que a transação seja validada. Se não for completada uma transação, seja porque for cancelada ou por um evento externo, as modificações não são guardadas.

Durante uma transação, todas as mudanças realizados aos dados do banco dentro do processo são armazenados localmente em um buffer temporário. Se a transação for aceita com VALIDATE TRANSACTION, as mudanças são guardadas de maneira permanente. Se a transação for cancelada com CANCEL TRANSACTION, as mudanças não são guardadas. Em todos os casos, nem a seleção atual nem o registro atual são modificados pelos comandos de gestão de transações.

A partir da versão 11, 4D é compatível com transações aninhadas, ou seja, transações em vários níveis hierárquicos. O número de subtransações autorizadas é ilimitado. O comando Transaction level permite conhecer o nível atual de transação no qual se executa o código.

Quando utiliza transações aninhadas, o resultado de cada subtransação depende da validação ou cancelação da transação de nível superior. Se for confirmada a transação de nível superior, os resultados das subtransações são confirmados (confirmação ou cancelamento). Do contrário, se a transação superior for cancelada, todas as subtransações são canceladas, sem importar seus resultados.

As transações aninhadas podem gerar disfunções nos bancos desenvolvidas com versões anteriores de 4D, por esta razão esta opção está desativada por padrão nos bancos convertidos (as transações ficam limitadas a um só nível). Se deseja aproveitar as transações em vários níveis em um banco convertido, deve ser indicado explicitamente selecionando a opção Permitir transações aninhadas na página “Aplicação/Compatibilidade” das Preferências da aplicação.

Esta opção aparece apenas em bancos de dados convertidos. Por padrão, não está selecionada e é específica para cada banco. Não tem efeito nas transações realizadas no motor SQL de 4D. As transações SQL sempre são multinível.

Neste exemplo, o banco é um sistema de faturação simple. As linhas das faturas são armazenadas em uma tabela chamada [Linha_Fatura], a qual está relacionada com a tabela [Faturas] por uma relação entre os campos [Faturas]NumeroFaturas e [Linha_Fatura]NumeroFaturas. Quando se adiciona uma fatura, um número único é calculado utilizando o comando Sequence number. A relação entre [Faturas] e [Linha_Fatura] é uma relação automática Muitos a um. A caixa de seleção Autoatribuir valor no subformulário está selecionada.

A relação entre [Linha_Fatura] e [Partes] é manual.

Quando um usuário introduz uma fatura, são executadas as seguintes ações:

  • Adição de um registro na tabela [Faturas].
  • Adição de vários registros na tabela [Linha_Fatura].
  • Atualização do campo [Partes]Em_Depósito de cada parte listada na fatura.

Este exemplo é uma situação típica na qual necessita utilizar uma transação. Necessita ter certeza de que vai poder salvar todos estes registros durante a operação ou de que poder cancelar a transação se um registro não puder ser adicionado ou atualizado. Em outras palavras, deve guardar os dados relacionados.

Se não utilizar uma transação, não pode garantir a integridade de dados lógica de seu banco. Por exemplo, se um registro da tabela [Partes] estiver bloqueado, não poderá atualizar a quantidade armazenada no campo [Partes]Em_Depósito. Este campo ficará então logicamente incorreto. A soma das partes vendidas e restantes em depósito não serão iguais a quantidade original introduzida no registro. Pode evitar tal situação utilizando as transações.

Há várias maneiras de introduzir dados utilizando transações:

1. Pode administrar as transações utilizando os comandos de transação START TRANSACTION, VALIDATE TRANSACTION e CANCEL TRANSACTION. Pode escrever, por exemplo:

 READ WRITE([Linha_Fatura])
 READ WRITE([Partes])
 FORM SET INPUT([Faturas];"Entrada")
 Repeat
    START TRANSACTION
    ADD RECORD([Faturas])
    If(OK=1)
       VALIDATE TRANSACTION
    Else
       CANCEL TRANSACTION
    End if
 Until(OK=0)
 READ ONLY(*)

2. Para reduzir os bloqueios de registros durante a entrada de dados, pode também selecionar administrar transações a partir do método de formulário e acessar as tabelas em READ WRITE apenas quando seja necessário.

Você realiza a entrada de dados utilizando o formulário de entrada para [Faturas], o qual contém a tabela relacionada [Faturas]Linhas em um subformulário. O formulário tem dois botões: bCancel e bOK, ambos são botões sem ações.

O loop de adição é convertido em:

 READ WRITE([Linha_Fatura])
 READ ONLY([Partes])
 FORM SET INPUT([Faturas];"Entrada")
 Repeat
    ADD RECORD([Faturas])
 Until(bOK=0)
 READ ONLY([Linha_Fatura])

Note que a tabela [Partes] está em modo de acesso "apenas leitura" durante a entrada de dados. O acesso leitura/escrita estará disponível apenas se os dados forem confirmados.

A transação é aberta no método de formulário de entrada da tabela [Faturas]:

 Case of
    :(Form event=On Load)
       START TRANSACTION
       [Faturas ]NumeroFaturas:=Sequence number([Faturas ]NumeroFaturas)
    Else
       [Faturas]Total_Fatura:=Sum([Linha_Fatura]Total_Linha)
 End case

Se clicar no botão bCancel, a entrada e a transação devem ser canceladas.

Este é o método de objeto do botão bCancel:

 Case of
    :(Form event=On Clicked)
       CANCEL TRANSACTION
       CANCEL
 End case


Se clicar no botão bOK, a entrada e a transação devem ser aceitas. Este é o método de objeto do botão bOK:

 Case of
    :(Form event=On Clicked)
       $NbLineas:=Records in selection([Linha_Fatura])
       READ WRITE([Partes]` Mudar o acesso leitura/escrita para a tabela [Partes]
       FIRST RECORD([Linha_Fatura]) ` Iniciar na primeira linha
       $ValidTrans:=True ` Assume que tudo estará OK
       For($Line;1;$NbLines` Para cada linha
          RELATE ONE([Linhaa_Fatura]NumeroParte)
          OK:=1 ` Assume que você deseja continuar
          While(Locked([Partes]) & (OK=1)) ` Tratar de obter o registro em acesso Leitura/Escrita
             CONFIRM("A parte "+[Linha_Fatura]NumeroParte+" está sendo usada. Esperar?")
             If(OK=1)
                DELAY PROCESS(Current process;60)
                LOAD RECORD([Partes])
             End if
          End while
          If(OK=1)
  ` Atualizar quantidade no depósito
             [Partes]Em Depósito:=[Partes]Em Depósito-[Linha_Fatura]Quantidade
             SAVE RECORD([Partes]` Guardar registro
          Else
             $Linha:=$NbLinhas+1 ` Deixar o loop
             $ValidTrans:=False
          End if
          NEXT RECORD([Linha_Fatura]) ` Ir para a linha seguinte
       End for
       READ ONLY([Partes]` Definir o estado da tabela em modo só leitura
       If($ValidTrans)
          SAVE RECORD([Faturas]` Guarda o registro Faturas
          VALIDATE TRANSACTION ` Confirmar todas as modificações ao banco
       Else
          CANCEL TRANSACTION ` Cancelar tudo
       End if
       CANCEL ` Deixar o formulário
 End case

Neste código, chamamos ao comando CANCEL sem importar em qual botão o usuário clique. O novo registro não está validado por uma chamada a ACCEPT, mas pelo comando SAVE RECORD. Além disso, note que SAVE RECORD é chamado imediatamente antes que o comando VALIDATE TRANSACTION. Portanto, guardar o registro [Faturas] é na verdade parte da transação. Chamar o comando ACCEPT também confirmaria o registro, mas neste caso a transação será validada antes de que o registro [Faturas] seja guardado. Em outras palavras, o registro seria guardado fora da transação.

Dependendo de suas necessidades, pode personalizar seu banco, como é mostrado nestes exemplos. No último exemplo, a gestão de bloqueio de registros da tabela [Partes] pode ser  mais desenvolvida.

 
PROPRIEDADES 

Produto: 4D
Tema: Transações

 
VER TAMBÉM 

CANCEL TRANSACTION
In transaction
START TRANSACTION
VALIDATE TRANSACTION

 
ARTICLE USAGE

Manual de linguagem 4D ( 4D v12.4)
Manual de linguagem 4D ( 4D v14 R3)
Manual de linguagem 4D ( 4D v14 R2)
Manual de linguagem 4D ( 4D v13.5)
Manual de linguagem 4D ( 4D v14.3)
Manual de linguagem 4D ( 4D v14 R4)

Inherited from : Usar Transações ( 4D v11 SQL Release 6)