O TOTVS | DBAccess adota, para a maioria dos bancos, o nível de isolamento READ UNCOMMITTED por não serializar as operações e a leitura dos registros. Com isto, pode haver leitura suja nas  operações de leituras da base de dados, isto é, a transação corrente pode obter dados das transações ainda não comitadas por outras conexões. 

O nível de isolamento adotado garante que as leituras realizadas no banco de dados pela aplicação não realizem bloqueio de registros e por consequência não serializem a aplicação, mantendo a previsibilidade do desempenho. Porém alguns cuidados devem ser observados para garantir a integridade dos dados.

Quando se adota leituras sujas deve-se prevenir que em atualizações, os dados sejam bloqueados antes de serem atualizados ou lidos com este fim.  A transação T2 tem uma linha alterada, mas ainda não finalizada. A transação T1 lê os dados atualizados e os atualiza com base nos dados lidos. A transação T1 fecha a transação e a transação T2 realiza um Roll Back dos dados. A partir deste momento os dados não estão mais íntegros.

Para evitar esta situação, o desenvolvedor deve indicar a aplicação o momento do bloqueio, isto é feito utilizando a função RecLock, conforme demonstrado abaixo:

// ReadSample.prw

Begin Transaction
  RecLock("SB2")
  nQtd := SB2->B2_QATU
  If nQtd + nSoma <= 0
    SB2->B2_QATU := 0
  Else
    SB2->B2_QATU := nQtd - nSoma
  EndIf
  MsUnlock()
End Transaction

A função RecLock informa para o Framework da aplicação realizar o bloqueio do registro posicionado. O Framework realiza o bloqueio e atualiza a leitura do registro corrente da tabela. As demais transações do sistema continuam lendo o registro bloqueado, porém se tentarem bloquear o registro deverá aguardar a transação anterior liberá-lo, o que somente pode ser realizado ao termino da transação.

Outra prevenção a ser considerada nas leituras sujas são as atualizações parciais, decorrentes do relacionamento de dependência direta das tabelas. Para um formulário do tipo Master/Detail (cabeçalho e Item), a transação de inserção deste formulário permite que o registro da tabela Master exista sem os registros ou com uma quantidade parcial dos registros da tabela Detail, haja vista que é a única forma de garantir a dependência da chave estrangeira. Se uma rotina de atualização realizar o bloqueio apenas nos registros Detail não há como garantir que todos os registros sejam considerados. Portanto é necessário bloquear o registro Master, antes do inicio do bloqueio dos registros Detail em qualquer atualização dos registros Detail. Ao bloquear o registro Master, garante-se que nenhum registro da tabela Detail, vinculado ao Master, esteja em atualização ou inserção. É fato que dependendo da rotina desenvolvida, é obrigatório iniciar a leitura pela tabela Detail e não pela Master. Nestas situações deve-se garantir que, antes de qualquer atualização do registro Detail, o registro Master seja bloqueado antes do registro Detail.

No exemplo são mencionadas apenas duas tabelas, porém independentemente da quantidade de tabelas envolvidas no formulário, o registro Master deve ser bloqueado.

Por último, existe a prevenção do momento do COMMIT. A arquitetura do Server Application da linha Microsiga Protheus faz com que o momento do COMMIT seja automático, conforme a lógica do programa, assim como pode utilizar mais de um canal de comunicação com o SGBD para leitura. Se o Server Application utiliza mais de um canal para leitura, é possível inferir que os demais canais de leitura somente “visualizarão” os registros, cujos dados foram comitados. Para prevenir qualquer tipo problema na leitura através de querys, é necessário forçar o COMMIT dos dados, conforme demonstrado abaixo.

// CommitSample.prw

SPED050->(DbCommit())
BeginSQL Alias cAlias
  SELECT R_E_C_N_O_
  FROM SPED050
  WHERE ID_ENT = %Exp:cIdEnt% AND
      (STATUS = 1 OR STATUS = 2 OR   STATUSDPEC = 1) AND
      STATUSDPEC <> 5 AND %NOTDEL%
EndSQL

O nível de isolamento READ UNCOMMITTED é o mais aconselhável para aplicação do tipo de aplicação OLTP (On Line Transaction Process),  porém cabe ao desenvolvedor o controle do formato de leitura e o bloqueio do registro para atualização.

  • Sem rótulos