Árvore de páginas

Introdução 

Quando realizamos um Trace através do DBAccess Monitor, para verificar quais instruções estão sendo enviadas pelo DBAccess ao Banco de Dados, podemos nos deparar com um cenário onde, num primeiro momento uma instrução de INSERT de registro é enviada, criando um novo registro marcado para deleção em uma tabela ( com o campo de controle D_E_L_E_T_ preenchido com "*" e o campo R_E_C_D_E_L_ preenchido com o número do R_E_C_N_O_ ), e logo abaixo uma nova instrução apenas realizando um UPDATE destes dois campos de controle, removendo o "*' do campo D_E_L_E_T_ e atualizando o campo R_E_C_D_E_L com o valor 0 (zero). O objetivo deste documento é explicar o que pode levar a aplicação a ter este comportamento. 

Comportamento esperado na inserção de novos registros

Quando um programa AdvPL é escrito, para trabalhar com qualquer banco de dados, ISAM ( DBF, CTREE ) ou SQL ( via TOPConnect ou DBAccess ), espera-se o seguinte comportamento:

  • Ao ser iniciada a inserção de um registro na aplicação AdvPL, por exemplo com uma chamada da função RecLock(<alias>,.T.) , deve ser criado um registro em branco, com um bloqueio exclusivo de escrita para o processo atual, onde todos os campos do ALIAS em questão estão preenchidos com os valores vazios para cada tipo de dado ( Campos C caractere com espaços em branco, campos numéricos com 0 (zero), campos D Data com uma data vazia, campos booleanos com o valor .F. (falso). 
  • Durante a operação de inserção, a aplicação AdvPL não precisa respeitar nenhuma ordem de preenchimento dos campos. 
  • Enquanto o bloqueio (ou Lock) do registro inserido não for solto, a aplicação pode alterar inclusive valores de campos já preenchidos, inclusive tal recurso é usado muito em pontos de entrada específicos do ERP Microsiga, quando tais pontos de entrada são chamados dentro de uma inserção, justamente antes de soltar o bloqueio do registro.
  • A qualquer momento, inclusive durante a alimentação de dados de um registro sendo inserido, a aplicação AdvPL pode consultar o número do registro atualmente posicionado. 

Optimização do processo pelo TOTVS Application Server

Para evitar a inserção de um registro em branco na base de dados, seguido de uma ou mais operações de atualização, o TOTVS Application Server não insere um registro em branco na hora na base de dados, ele apenas cria um registro em branco na memória  e passa a receber os valores a serem atualizados neste registro, para fazer a operação de inserção de uma vez, normalmente quando a aplicação solicita um flush das informações para o Banco de Dados ( função DBCommit() ) ou mesmo o final da inserção, onde o bloqueio é solto ( MSUnlock() ). Este é o comportamento ideal de uma rotina de inserção, encaminhar ao banco de dados apenas uma instrução com todos os campos preenchidos pela aplicação para serem inseridos. 

Exceção - Utilização da função RECNO()

Se, durante a inserção de um registro, enquanto os campos já preenchidos do registro estão na memória do servidor de aplicação AdvPL, o programa chama a função RECNO(), para recuperar a chave primária de identificação (ou seja, o número do registro), este número é necessário a partir do momento em que for requisitado, e deve ser o número REAL do registro efetivamente gravado na base de dados. Neste momento, e neste caso, o TOTVS Application Server envia ao DBAccess a inserção de um registro com a marca de "deletado", pois não há nenhuma garantia que, até esse momento, a aplicação AdvPL já tenha preenchido todos os valores dos campos com seus respectivos conteúdos, e uma inserção definitiva com campos não preenchidos pode causar uma violação de índice único da tabela em questão. A única forma de fazer uma inserção física que obtenha um número real sem violar a chave única é inserir o registro deletado. Uma vez feito isso, a aplicação já têm o número do registro para controle, e no momento que for feito novamente um flush dos dados do registro – DBCommit() ou MsUnlock() – o TOTVS Application Server vai enviar ao DBAccess o update dos dados dos campos preenchidos desde a inserção efetiva, e inclusive o update para remover a marca de deleção de registro e atualizar os campos de controle R_E_C_N_O_ e R_E_C_D_E_L_. 

Houve a necessidade de implementar este mecanismo, para respeitar as premissas de comportamento esperado pela aplicação AdvPL: O conteúdo final do registro após a inserção no Banco de Dados somente é considerado como conteúdo "final" quando a aplicação AdvPL solta o bloqueio do registro, o que normalmente ocorre na chamada da MSUnlock(), ou em caso de programas transacionados, os locks são soltos apenas no END TRANSACTION. Enquanto isso, os campos do registro em inserção podem ser alterados uma ou mais vezes pela aplicação Advpl antes do lock / bloqueio ser solto. 


  • Sem rótulos