Como você lida com vários usuários editando o mesmo dado em um aplicativo da web?

26

Há um projeto no qual estou trabalhando que procura produzir um aplicativo Web que gerencie uma lista de tarefas entre vários usuários. Esta é uma lista de tarefas principal cujos itens de tarefa são distribuídos por um usuário autorizado. Cada usuário tem sua própria conta para efetuar login e visualizar as tarefas que foram atribuídas; é possível que vários usuários tenham uma única tarefa em comum.

Estou tentando deixar os detalhes do projeto fora disso, pois estou lidando mais com o conceito geral de como lidar com as situações a seguir, mas se ajudar, estou usando Java, EclipseLink e GWT com RequestFactory implementado. O banco de dados é PostgreSQL.

Portanto, os problemas conceituais que estou tentando reconciliar são os seguintes:

  1. Se uma única tarefa comum a vários usuários mudar de alguma forma, por exemplo, tarefa concluída, excluída etc., a lista de tarefas de todos os usuários que possuem essa tarefa será atualizada. Quais padrões de design existem para auxiliar na implementação dessa função?

    • Alguns padrões que observei são o Observador e o Mediador - existem outros que devem ser considerados sobre eles?
  2. Digamos que haja dois usuários alterando a mesma tarefa ao mesmo tempo.

    • Primeiro, devo permitir que essa situação aconteça ou devo trancá-la até que uma ou outra pessoa termine de fazer alterações?

    • Segundo, se eu não coloco uma trava nela, como reconcilio as alterações a serem aceitas? Isso envolve a situação em 1 porque o usuário 1 pode enviar os dados e antes que o usuário 2 receba os dados atualizados, ele / ela pode ter ido em frente e enviado as alterações dele.

Estou realmente procurando pontos de orientação, conselhos ou dicas que você possa fornecer sobre como sincronizar dados corretamente entre várias instâncias deste aplicativo Web. Eu apreciaria isso muito!

hulkmeister
fonte

Respostas:

17

Acho que o Whiteboard será o seu padrão de escolha para o número 1; você deve publicar alterações em tarefas (ou outros dados compartilhados) em um local comum, para que todas as partes interessadas possam vê-las e a DTRT.

Para o número 2, você precisa observar o bloqueio otimista . Basicamente, você precisa registrar o registro de data e hora de todos os seus registros editáveis ​​com a última atualização. Ao tentar salvar o registro, verifique primeiro se o registro no banco de dados possui o mesmo registro de data e hora da última atualização que o registro. Caso contrário, alguém atualizou o registro e agora você precisa obtê-lo e informar ao usuário que eles precisam inserir suas alterações novamente ou pode tentar mesclar as alterações do usuário no registro atualizado (o que geralmente resulta ser simples ou impossível).

TMN
fonte
7

Eu criei um design para um aplicativo de desktop (que ainda não foi totalmente testado) com requisitos semelhantes que podem ser úteis.

Minha solução foi empregar o padrão MVC (com um único modelo, mas vários controladores e exibições) em que cada controlador fazia alterações no modelo usando transações (usando STM ) e, quando uma transação era confirmada, o modelo transmitia uma notificação de atualização para as visões. )

Todos os clientes também mantinham o controle de qualquer coisa que estivesse sendo atualizada localmente, mas quando essas atualizações locais foram concluídas (ou seja, enviadas para serem confirmadas), ele voltou a usar as informações do Modelo subjacente.

Também tive uma pilha de desfazer com todas as alterações feitas pelos usuários para que as coisas pudessem ser revertidas.

Esse pode não ser o melhor modelo para um aplicativo Web, já que o Modelo teve que transmitir alterações para as Views, o que pode não ser o mais fácil para um cliente Web.

Paulo
fonte
4

para 1. você deve ver se o padrão de publicação / assinatura é mais adequado.
para 2. depende da sua situação:

  • Quão frequente será essa situação?
  • Quão ruim é uma situação em que um de seus usuários não conseguirá atualizar uma tarefa porque ela está bloqueada ou alguém o alterou nesse meio tempo?
    pessoalmente, prefiro uma abordagem (usada, por exemplo, no pivotaltracker ), na qual existem:
    • sem fechaduras,
    • você vê todas as alterações em tempo real e
    • a interface do usuário convida a fazer atualizações secundárias frequentes em vez de maiores em vários atributos.
    • você mantém um histórico de todas as alterações que foram feitas. se o histórico estiver visível para os usuários, conflitos ou substituições que possam surgir podem ser resolvidos com comentários, anotações ou mensagens.
kr1
fonte
A questão é mais acadêmica, por isso vou dizer com muita frequência para ver como é resolvida na pior das hipóteses. +1 para as referências de padrão.
Hulkmeister
O @ pivotaltracker do kr1 não possui aviso de conflito e não mescla alterações não conflitantes; portanto, não deve ser usado como um bom exemplo de um bom aplicativo multiusuário para edição de registros.
Eduardo
0

Minha recomendação é nunca bloquear e relatar um conflito, se isso acontecer.

Por favor, dê uma olhada em:

https://github.com/spring-projects/spring-petclinic/issues/433

Você pode ver um vídeo e um código de amostra.

Isso atenderá às suas necessidades?

Eduardo
fonte