Pattern - Cadastro/Aprovação/Publicação

Pessoal, bom dia

Estou me deparando com 1 cenario e queria a opiniao de vcs:

Tenho 1 sistema onde um usuário qualquer irá se logar e “manter” os registros, digamos assim. Inserir, alterar, etc… Em determinado momento, ele “submete” os dados
para aprovação, momento em que passam a ser visíveis para um outro usuário, que podemos chamar de usuário “aprovador”. Em 1 outro momento, esse mesmo usuario aprovador ira entrar no sistema para publicar esses dados, momento em que passam a ser visíveis num portal para usuários sem autenticação.

Eu me deparei com 1 problema ao tentar modelar o banco pelo seguinte: Se após a submissao dos dados, eles passassem a ser visíveis pro usuario aprovador e o usuario cadastrador nao pudesse mais editar o registro, tudo bem. O problema é que nao funciona assim. Após a submissao dos dados, eles podem ser aprovados pelo usuario aprovador, mas o usuario cadastrador pode continuar a inserir novos registros, ou mesmo alterá-lo.

Ai vem a duvida: como evitar o fenômeno de “ghost read”? Ex: o cara cadastra 1 contrato de 1milhao, com 3 aditivos de 200.000 (total= 1.600.000)
Na hora em que ele clica em APROVAR, 2 segundos antes o cadastrador insere mais 2 aditivos.
Resumindo: o aprovador aprovou coisas que nao visualizou.
Avisar o usuario, no momento que for aprovar efetivamente, que os dados foram alterados e “recarregar” a tela, NAO é opção. Deve ser assincrono, os 2 usuarios devem trabalhar livremente sem depender 1 do outro, e caso o usuario aprovador aprove, deve aprovar somente os dados que foram submetidos.

Por enqto a unica solucao que cheguei (que ta 1 bad smell danado) é, de pra cada tabela que for sofrer aprovação (ex: Contrato), existir tambem uma tabela “ContratoHomologacao”, na qual ira estar os dados “Aguardando Aprovacao”. Eles sao transferidos pra essa tabela no momento da “submissao” dos dados, pelo usuario cadastrador. O usuario aprovador trabalha entao em cima dessa tabela, ContratoHomologacao

Sugestoes? Dei uma lida nos Workflow Patterns e State Patter, mas nao ajudaram muito. (ate pq sao para problemas diferentes, pelo q entendi)

Apesar de nunca ter utilizado esse recurso do hibernate/jpa, acredito que seja a solução para seu problema:

http://docs.jboss.org/envers/docs/index.html#quickstart

Assim você irá versionar de fato suas entidades, após isso você terá que escolher a estratégia de homologação. Talvez uma simples coluna esta_homologado (0|1) seja suficiente, pois se acontecer como penso que seja - cada versão da entidade ficar em um tupla separada (ou virtualmente separada, com esta_homologado anotado com auditável), então você terá o status de homologado para cada versão da sua entidade. Confere?

Condicionado a você estar usando hibernate/jpa, claro.

Abraço

Sim brother, eu tinha cogitado usar o envers, eu utilizo HB/JPA mas no desenrolar da analise acabou nao sendo viável, pois essa tabela ele gera de forma automatica e customiza-la (adicionar campos para meu controle) parece que nao é tao simples. Além de continuar tendo os problemas de concorrencia que te falei la em cima.

Queria saber se existia algo a nivel de pattern mesmo, até porque esse cenario pode se repetir num ambiente onde eu nao tenho hibernate

Acredito que evitarás que essa situação ocorra é a utilização de Isolation, mas isso vai depender SE O BANCO DE DADOS suporta.

Enfim, não custa tentar :slight_smile:

Se tu estás usando Hibernate com Spring por exemplo, tu podes fazer o seguinte: Anote o método transacional e defina um isolation.

Infos de Oracle: http://download.oracle.com/docs/cd/B14117_01/server.101/b10743/consist.htm -> explica certinho também o que é cada nível :smiley:

Um pouco sobre Isolations: http://www.expresscomputeronline.com/20040426/techspace01.shtml -> usando SQL Server

Maiores informações no Hibernate: http://docs.jboss.org/hibernate/core/3.3/reference/en/html/transactions.html

Caso você esteja usando Spring: http://static.springsource.org/spring/docs/3.0.x/reference/transaction.html

EDIT: coloquei IMG ao invés de URL. Sou noob do fórum >/

Como você disse que dizer para o aprovador que os dados foram alterados não é solução, fiquei curioso com o fluxo de trabalho que quer.

Eu vejo dois tipos de solução conceituais:

  • Lock pessimista: Se quem submete está editando, aprovador não abre. Se aprovador está aprovando, editor não abre.
  • Lock otimista: Todos podem editar a qualquer momento e SE houver conflitos, eles são notificados

Qual modelo de abordagem atende?

Fala Leozin/Abel

Entao… NAO pode existir lock… Nem pessimista, nem otimista.

Se o cara submete determinados registros, o aprovador pode APROVAR tais registros que foram submetidos nao importa as alterações que forem realizadas pelo usuario cadastrador, desde a última submissão. Os 2 processos (cadastramento/aprovacao) funcionam independentes, em momentos diferentes e um nao pode “lockar” o outro.

Por isso que nesse caso, nenhuma abordagem de isolamento/notificação resolve.

Desculpe, mas então o que o sistema deve fazer quando o cara aprovar algo que foi alterado (e portanto não existe mais) ?

Se o cara alterou, mas nao passou novamente pelo processo de aprovação? continua como está (sim, é meio esquisito, mas são dados que digamos assim ja foram publicados, dados de contrato que o governo ja gastou dinheiro).

O “não existe mais” não acontecerá. Ira acontecer o (está aprovado 1 milhao, mas na REAL ja esta em 1 milhao em 400mil - 400 ainda nao aprovados).

Hum…agora entendi…pensei que os dados poderiam ser editados, mas na verdade só há inclusão de mais informações.

Não conheço nenhum padrão clássico para isto.

O que eu faria era associar um status para cada item (ou múltiplos, dependendo da necessidade).

Imagino que em todas consultas que fizer, terá que mostrar sempre duas visões (aprovada e submetida).
Com esse status já conseguiria manter essa visualização.

Claro que o status seria do detalhe (cada adicional de contrato) e não para o grupo todo.