Pergunta

Um membro da equipe foi executado em um problema com um antigo sistema in-house onde um usuário clicar duas vezes em um link em uma página da web pode causar dois pedidos para serem enviados a partir do navegador, resultando em duas inserções de base de dados do mesmo registro em uma condição de corrida; o último a correr falha com uma violação de chave primária. Várias soluções e hacks foram propostos e discutidos:

  1. Use Javascript na página web para mitigar o segundo clique, desativando o link no primeiro clique. Esta é uma maneira rápida e fácil para reduzir as ocorrências do problema, mas não totalmente eliminá-lo.

  2. Enrole a execução do pedido no lado do sever em uma transação. Este foi considerado demasiado caro de uma operação devido a níveis de carga e bloqueio de servidor na tabela em questão.

  3. capturar a exceção de chave primária jogado pela inserção falhou, identificá-lo como tal, e comê-lo. Isto tem as desvantagens do (a) vendor lock-in, ter de conhecer as nuances das exceções específicas do banco de dados, e (b) potencialmente não log / lidar com falhas de banco de dados legítimos.

  4. Uma extensão do nº 3 ao tentar atualizar o registro se a inserção falha e verificar o resultado da atualização para garantir que ele retorna 1 registro afetado.

são as outras opções que não foram considerados? Existem prós e contras das opções apresentadas que foram ignorados? Que é o menor de todos os males?

Foi útil?

Solução

Você precisa implementar o padrão sincronizador Sinal.

Como funciona é: um valor (o token) é gerado no servidor para cada solicitação. Esta mesma razão deve, então, ser incluído no seu envio do formulário. Após a recepção do pedido, o servidor token e cliente de token são comparados e se eles são os mesmos que você pode continuar a adicionar seu registro. O token do lado do servidor é então regenerado, os pedidos para que subsequentes contendo o token antigo irá falhar.

Há uma explicação mais completa sobre meio caminho desta página .

Eu não tenho certeza o que a tecnologia que você está usando, mas Struts fornece suporte de nível estrutura para esse padrão. Veja o exemplo aqui

Outras dicas

Coloque um identificador exclusivo na página em um campo escondido. Apenas aceitar uma resposta com um dado identificador único.

Parece que você pode estar fazendo mau uso de um pedido GET para modificar o estado do servidor (embora este não é necessariamente o caso). Embora possa não ser adequado para você situação, deve-se afirmar que você deve considerar a conversão do link em um POST formulário.

Parece que você já respondeu a sua própria pergunta lá; # 1 parece ser a única opção viável.

Caso contrário, você deve realmente fazer todos os três passos -. Integridade dos dados deve ser tratado no nível de banco de dados, mas verificações extras (como a transação explícita) no código para evitar roundtrips para o banco de dados poderia ser bom para o desempenho

REF que você precisa para implementar o padrão sincronizador Sinal.

Isto é para JavaScript / HTML não JAVA

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top