FANDOM


Este tutorial explica como é possível realizar uma gravação sem possuir conexão com o banco de dados. Este recurso é extremamente desejado em sistemas de varejo, onde, por exigência do convênio ICMS 85, um PDV deve operar estando desconectado da rede. O caixa da Inteq baseia-se fortemente nas idéias apresentadas abaixo.

A idéia é simples. Vc deve criar uma tarefa no scheduler para realizar o applyUpdates em background.

Esta abordagem é muito simples quando estamos adicionando registros de tabelas que não fazem parte do cache local, mas quando fazem percebemos alguns incovenientes que devem estar na mente do desenvolvedor:

 - A atualização do cache local da estação deverá ser feita manualmente;
 - Os outros caches dentro da mesma rede não receberão a atualização do cadastro;
 - Reiniciar o sistema irá perder as informações gravadas, pois o cache retornará para a posição da última sincronia com o banco de dados;
 - Não é permitido realizar mais de uma alteração cadastral para o mesmo registro. A segunda edição deve ser bloqueada para que não seja adicionada uma tarefa que sempre retornará o erro "A chave foi alterada por outro usuário...". Isto pode ser feito checando se já existe uma tarefa criada para a mesma chave de cliente no scheduler;

Abaixo um trecho de um código do caixa que exemplifica o funcionamento:

  // Desliga a gravação automática no banco de dados, pois não quero levantar erro
  //   caso o sistema esteja off-line.
  entidade.automaticApplyUpdates = false
  entidade.append()
  // Altera campos do dataSet entidade
  
  var task = new Task()
  task.scriptKey  = -1898188327 /* cScriptGravarDataSets */
  task.period     = 'once'
  task.retry      = true
  task.setParameters( 'dsArray', [ entidade ] )
  task.name = 'Gravando cadastro do cliente ' + entidade.nome + ' ( "' + entidade.chave + '" )'
  task.saveLocally()
  // Apago o Delta do clone do Cache Local. O registro ficará gravado no cache da máquina sem versão,
  //   enquanto a tarefa recém criada irá gravar no banco e consequentemente atualizar o cache com
  //   a versão correta.
  entidade.cancelUpdates()

O código utilizado por esta tarefa (-1898188327) é simples:

  // ATENÇÃO : Este script verifica se um possível erro trata-se de uma edição por outro usuário.
  //   Neste caso, a ocorrência do problema vai para o LOG e a tarefa é concluída como se tudo estivesse OK.
  //   Este comportamente é desejado para evitar que um possível retry desta tarefa fique rodando infinitamente.
  //   O usuário deste script deve se lembrar deste comportamento.
  //   Este script aborta gravações com erro de chave duplicada.
  try {
     connection.applyUpdates( dsArray )
  } catch (e) {
     var message = e.message.toLowerCase()
     if ( message.indexOf( 'alterad' ) >= 0 ) {
        log.write( 'A tarefa Gravar DataSets foi abortada, pois uma informação contida em um dos dataSets foi alterada por outro usuário. ' + e.message )
     } else {
        // O scheduler não pode garantir 100% que uma tarefa não será chamada duas vezes. Tendo detectar este problema abaixo.
        // cannot insert duplicate key => SQL Server 7/2000
        // unique constraint => Oracle 9i
        if ( ( message.indexOf( 'annot insert duplicate key' ) >= 0 ) || ( message.indexOf( 'unique constraint' ) >= 0 ) ) {
           log.write( 'A tarefa Gravar DataSets foi abortada, pois um dos dataSets está tentando inserir chaves duplicadas. ' + e.message )
        } else {
           throw e
        }
     }
  }

A versão 3.3.2.x poderá trazer impactos nos códigos acima, pois nela não existirá o conceito de snapshot do cache na entrada do sistema. O cache sempre estará sincronizado com o arquivo em disco.

Por um lado isto é positivo, pois reiniciar o sistema não perderá os dados gravados no cache. Porém, a priori, iriamos bloquear a alteração do cache que não fosse gravada no banco de dados, o que inviabilizaria a idéia acima. Este bloqueio será necessário para impedir que o programador "destrua o cache local". Este tipo de perversidade se tornará muito mais grave na versão 3.3.2.x, pois reiniciar o sistema não voltará o cache a um estado pré-destruição.

A verdade é que ainda não temos certeza de como funcionará a atualização do cache local e quando este assunto for decidido, iremos informar aos usuários do sistema. Estamos levando em conta, muito em conta, a demanda acima. De alguma forma deveremos manter a possibilidade do sistema operar off-line. As soluções já imaginadas são:

1)Manter um outro arquivo a parte do cache local para controlar a pendência de gravação no banco de dados;

2)Criar uma API para criar registros sujos no cache local que serão descartados na entrada do sistema.

Interferência de bloqueador de anúncios detectada!


A Wikia é um site grátis que ganha dinheiro com publicidade. Nós temos uma experiência modificada para leitores usando bloqueadores de anúncios

A Wikia não é acessível se você fez outras modificações. Remova o bloqueador de anúncios personalizado para que a página carregue como esperado.

Também no FANDOM

Wiki aleatória