2. Muitos administradores de bases de dados (DBMSs) contam com sistemas de recuperação anti-
falhas, que permitem deixar a base de dados em estado consistente quando ocorrem imprevistos tais
como apagões ou quedas do sistema.
3. Os administradores de bases de dados (DBMSs) que oferecem integridade transacional, permitem
estabelecer Unidades Lógicas de Trabalho (UTLs), que são, nem mais nem menos, que o conceito
de transações de base de dados.
4. Efetuar COMMIT em uma base de dados, significa finalizar uma Unidade Lógica de Trabalho (UTL).
5.
6. É importante comentar que o GeneXus inclui a sentença COMMIT nos programas gerados associados a
transações e procedimentos, somente em ambientes de trabalho Cliente/Servidor (incluindo, portanto, os
ambientes Web). O motivo disto é que em ambientes Cliente/Servidor, temos um DBMS que assegura a
integridade transacional, portanto o GeneXus efetua a tarefa de definir as Unidades Lógicas de Trabalho
(UTLs).
Onde o GeneXus inclui COMMIT exatamente?
Em cada procedimento: ao final do programa fonte.
Em cada Transação: imediatamente antes das regras com evento de disparo AfterComplete. Para cada
interação completa que for efetuada em tempo de execução por meio da transação, haverá um COMMIT,
antes das regras com evento de disparo AfterComplete.
Nota: o novo tipo de dados Business Component que estaremos vendo depois permite atualizar a base de
dados desde qualquer objeto GeneXus, mas será visto que não realiza automaticamente um COMMIT.
7. GeneXus oferece uma Propriedade para cada objeto transação e procedimento, para definir se
deseja que seu programa gerado efetue ou não o COMMIT. O nome da Propriedade é Commit
on Exit e seu valor por default é Yes (por isso, toda transação e procedimento por default efetua
COMMIT).
Se desejamos que certa transação ou procedimento não tenha COMMIT no programa gerado,
alterar o valor da Propriedade Commit on Exit para No.
8. Por que motivo pode-se querer que não seja realizado COMMIT em uma Transação ou
Procedimento?
Para personalizar uma Unidade Lógica de Trabalho (UTL). Isto é, podemos precisar ampliar uma
Unidade de Trabalho Lógica (UTL), para que várias transações1 e/ou procedimentos, estejam em uma
única Unidade de Trabalho Lógica (UTL).
Exemplo (mostrado acima):
A Transação “X” chama um Procedimento “Y”, e deseja-se que ambos objetos estejam em única UTL. A
Transação atualiza certos registros, e o procedimento outros, e se deseja que esse conjunto total de
operações, consista em uma única UTL (para assegurarmos que se ocorrer alguma falha, seja realizado
todo o conjunto de atualizações ou nada na da base de dados).
Para isto, podemos eliminar o COMMIT do procedimento, e deixar que seja realizado na Transação (ao
retornar do procedimento para a Transação, para que seja executado ao final de todas as operações);
temos que configurar a propriedade Commit on Exit do procedimento com valor: No e deixar a
propriedade Commit on Exit da Transação com o valor por default: Yes. Mas além disso, é fundamental
que a chamada ao procedimento seja realizada antes que se execute o COMMIT na transação (já
que a idéia é que ambos os objetos tenham uma única UTL, e para ele o COMMIT deve efetuar na
transação ao retornar do procedimento); assim que a chamada ao procedimento definir na Transação
com um evento de disparo que ocorra antes da execução do COMMIT (dependendo se a transação tiver
um nível ou mais, e dos requerimentos, poderia ser AfterInsert por exemplo, AfterUpdate, ou AfterLevel
Level Atributo do 2do nível, ou BeforeComplete mas não AfterCompete).
Não existe uma única solução para personalizar uma UTL. O fundamental é analisar qual objeto pode
fazer COMMIT (podendo haver mais de uma possibilidade) e uma vez que se decida qual objeto
efetuará COMMIT, as chamadas que se requerem fazer, deverão ser efetuadas em momentos
adequados, considerando se já executou o COMMIT ou não.
________________________________________________________________________________
¹ Em ambiente Web existe uma restrição importante: se uma transação chamar outra transação, o Commit realizada
por uma não aplica sobre os registros ingressados/modificados/eliminados pela outra. Isto é, o Commit de cada
transação contém somente “visibilidade” sobre os registros operados por essa transação, e não por outra, onde duas
transações diferentes não podem ficar em uma mesma UTL. Não poderá realizar-se personalização neste caso.
9. Por Exemplo, para que a transação e procedimento vistos conformem uma única UTL, poderíamos ter optado
também pela alternativa de que não efetue COMMIT na transação (Commit on Exit = No), mas sim que seja
realizado pelo procedimento ao final de tudo; fazer dessa forma, não seria um erro - como o é na solução
anterior - chamar ao procedimento utilizando o evento de disparo AfterComplete, o COMMIT não será realizado
na transação, mas no procedimento.
Concluindo, precisamos decidir qual objeto fará COMMIT e que as chamadas necessárias sejam feitas em
momentos adequados, para que a UTL personalizada fique bem definida.
Outro Exemplo:
A transação “Invoice“ estudada até o momento, em um modelo de Protótipo cliente/servidor. Caso não
modificarmos o valor predeterminado da propriedade Commit on Exit.
E o usuário executa a transação, inserindo a fatura 1 e todas as suas linhas. Depois insere a fatura 2 e quando
inserir a 3era. Linha da mesma ocorre um apagão. Quando a energia volta e reinicializa a execução, quais os
registros que ficaram gravados na tabela e quais foram perdidos?
A fatura 1 inteira estará gravada (cabeçalho e suas linhas). Por quê? Porque ao terminar de inserir e passar a
inserir a fatura 2, foi efetuado um commit. A fatura 2 com os registros que gravou até o momento que faltou
energia, foi perdido. Por quê? Porque a transação realiza o rollback de tudo que foi efetuado depois do último
commit. O cabeçalho da fatura 2 e as suas linhas informadas não estavam ainda “commitadas”.
Observar então que o commit não é pela transação inteira (ou seja, todas as interações do cabeçalho e suas
linhas) e sim por cada instancia do cabeçalho e linhas.
Se o commit acontece uma única vez antes da transação ser fechada, então se tivesse sido ingressados 29
faturas e o sistema caísse na trigésima, todas as 29 faturas anteriores (todo o processo seria desfeito, já que
ainda não foi realizado o commit). Isto não é assim, quando ocorre a queda do sistema na trigésima fatura
informada, ficaram gravadas as 29 anteriores (só não foi à trigésima).
10. Em ambiente Web os registros “visíveis” para ser commitados por uma transação são os atualizados
pela própria transação, e pela própria transação, e pelos procedimentos que esta chame antes do
seu Commit, porém não os de outra transação.
Cada transação trabalha com diferentes UTLs.
É por este motivo que no primeiro exemplo acima apresentado, onde a transação “X” chama a
transação “Y” logo de ter inserido um registro, embora a transação “Y” realize um Commit ao final do
cabeçalho e linha são ingressadas, este Commit não valerá sobre o registro que teria sido ingressado
previamente pela transação “X”. Este registro ficará “perdido”, sem Commit.
Internet trabalha de forma diferente, as transações Web “vivem” somente o tempo em que o usuário
de um navegador seleciona o link ou pressiona um botão e a nova página é mostrada. Toda
modificação da base de dados que se faça durante a “vida” da transação deve ser confirmada ou
eliminada antes que a transação Web finalize sua execução e retorne à página resultante.
Como conseqüência, uma transação Web inicia uma UTL (Unidade Lógica de Trabalho) ao começar
a executar e fecha-a (seja por COMMIT ou ROLLBACK) antes de terminar. Não pode formar parte de
outra UTL. Se um programa chama uma transação Web, esta iniciará outra (nova) UTL.
Não acontece isso com os procedimentos. No segundo exemplo mostrado acima, vemos que
podemos formar uma UTL que envolva à transação “Y” e ao procedimento “Z”...com tudo não
podemos incluir a transação “X” na mesma UTL.
11. Caso seja necessário que as operações de duas ou mais transações (com ou sem procedimentos
incluídos) estejam em uma mesma UTL, pode-se usar as transações com Web Panels e Business
Components; e utilizar o comando Commit.
Aqui simplesmente vamos deixar o tema sinalizado, voltaremos nele após estudar Business
Components, onde vamos compreender esta solução.