Falsos problemas ligados a persistência de objetos

(english)

Já faz alguns anos, pouco depois que conheci data types orientados a objetos, que também conheci alguns itens que faz com que algumas pessoas abominem a abordagem OO para manipulação de dados e objetos persistíveis (nota: com objetos persistíveis quero dizer qualquer objeto que possa ser armazenado para futura recuperação; se a palavra não existia, acabei de inventar 😉 ). A maior parte da culpa cai sobre o OPF.

OPF é lento

Temos um sistema cuja última versão estável tem um problema peculiar. Ele possui um modelo complexo, um de seus objetos de negócio possui dois containeres, e um destes containeres possui outros três. Isto significa que chega a ter três níveis de master-detail (ou seja, master-detail-subdetail). A consulta de uns 15 ou 20 objetos é rápida para descobrir quais são estes 15 ou 20, o problema é colocá-los no Grid. Quando a consulta é executada, é perceptível a montagem linha a linha do grid, e em uma segunda passagem, a montagem linha a linha de informações que estão em alguns containeres.

Esta lentidão acontece por causa da carga sob demanda. Objetos não são criados imediatamente, ao invés disto são armazenados seus OIDs em memória para que seja recuperado quando necessário. Acontece que a recuperação destes objetos ocorre um a um, gerando muito tráfego com pouco conteúdo, dificultando o trabalho do banco de dados, da rede e do sistema como um todo. Trazer todos os dados seria pior, pois iria gerar muito tráfego e muito trabalho inútil para o banco.

OPF causa problemas em alterações concorrentes

Frameworks de persistência costumam guardar em memória informação sobre o estado do objeto de quando ele foi lido, desta forma o framework saberá se o objeto foi ou não alterado em outra sessão. Isto é problema em casos que não precisem nem devam gerar conflito, como uma atualização da quantidade em estoque. Pior seria permitir que o framework grave o objeto sem se preocupar com alteração concorrente, conforme este exemplo:

  • Usuário 1 lê objeto
  • Usuário 2 lê objeto
  • Usuário 1 incrementa estoque em duas unidades (passa de 5 para 7)
  • Usuário 2 incrementa estoque em uma unidade (passa de 5 para 6)
  • Usuário 1 grava alteração
  • Usuário 2 grava alteração

O problema: o estoque fica em 6, ao invés de 8.

OPF exige ler um objeto inteiro para executar uma alteração mínima

Uma alteração de preços em massa. Todos os produtos de determinada categoria terão um aumento de X % em seu valor. É necessário ler todos os objetos, aplicar a alteração e gravar os objetos de volta, e isto é muito mais lento do que executar uma query diretamente no banco.

Mas todo problema tem uma solução

A lentidão do OPF está ligado ao fato de ler objetos em passo de tartaruga. Um recurso que eu chamo de bulk retrieving permite a leitura de uma lista de OIDs em poucas queries. Em geral deverá haver uma query para cada classe diferente; se a lista de OIDs fizer referência a objetos de uma única classe, uma única query trará todos estes objetos do banco de uma única vez. Basta configurar este retrieving para que, ao ler o primeiro OID que não esteja em cache, lê os próximos 30, 50, 100 objetos junto com ele.

As alterações concorrentes que não deveriam travar são geralmente relacionadas a atualização de valor. Exemplo, aumentar ou diminuir um determinado campo em tantas unidades. Isto é possível abrindo um espaço no data type para que ele guarde este tipo de atualização, exemplo:

  Produto.Estoque.Increment(Quant);

O OPF reconhecerá este tipo de alteração, e ao invés de fazer um update com o resultado, faz um update incrementando o próprio campo em “Quant”.

Alterações em lote podem ser executadas diretamente contra o banco de dados, o que irá solucionar o problema contanto que quem faça uso deste recurso tenha cuidado em manter o banco íntegro para o OPF. Não é uma tarefa complexa, exige apenas um pouco de atenção.

Por fim, reconheço que ainda existem problemas de solução difícil para o mundo OO no quesito persistência de objetos:

  • a curva de aprendizado é maior, e somente será viável se houver empenho do programador
  • é preciso um framework robusto, escalável, produtivo e em contínuo desenvolvimento, e isto deixou de ser problema com o nascimento do PressObjects SDK 😉

One thought on “Falsos problemas ligados a persistência de objetos”

  1. Belo post! Acho legal você falar a respeito desses ‘mitos’ e comentar sobre as formas de contorná-los ou mesmo resolvê-los. Já vi diversas vezes comentários dizendo que OOP e OPF não foram criados para sistemas comerciais, mas as soluções que você apresentou para os problemas citados me parecem perfeitamente aceitáveis.

Comments are closed.