Question

Un membre de l'équipe a rencontré un problème avec un ancien système interne: un utilisateur qui double-clique sur un lien d'une page Web peut envoyer deux demandes à partir du navigateur, ce qui entraîne deux insertions de base de données du même enregistrement. en situation de compétition; le dernier à exécuter échoue avec une violation de clé primaire. Plusieurs solutions et hacks ont été proposés et discutés:

  1. Utilisez Javascript sur la page Web pour atténuer le second clic en désactivant le lien au premier clic. C’est un moyen simple et rapide de réduire le problème, sans toutefois l’éliminer complètement.

  2. Emballe l'exécution de la requête du côté serveur dans une transaction. Cela a été jugé trop coûteux pour une opération en raison de la charge du serveur et des niveaux de verrouillage de la table en question.

  3. Attrapez l'exception de clé primaire levée par l'insertion ayant échoué, identifiez-la comme telle et consommez-la. Cela présente les inconvénients suivants: (a) une immobilisation des fournisseurs, qui doivent connaître les nuances des exceptions spécifiques à la base de données, et (b) une éventuelle non-journalisation / gestion des défaillances de base de données légitimes.

  4. Une extension de # 3 en tentant de mettre à jour l'enregistrement si l'insertion échoue et en vérifiant le résultat de la mise à jour pour s'assurer qu'il renvoie 1 enregistrement affecté.

Les autres options n’ont-elles pas été considérées? Y a-t-il des avantages et des inconvénients des options présentées qui ont été négligés? Quel est le moindre de tous les maux?

Était-ce utile?

La solution

Vous devez implémenter le modèle de jeton de synchroniseur.

Voici comment cela fonctionne: une valeur (le jeton) est générée sur le serveur pour chaque demande. Ce même jeton doit ensuite être inclus dans la soumission de votre formulaire. Dès réception de la demande, le jeton de serveur et le jeton de client sont comparés et, s'ils sont identiques, vous pouvez continuer à ajouter votre enregistrement. Le jeton côté serveur est ensuite régénéré. Par conséquent, les requêtes suivantes contenant l'ancien jeton échoueront.

Il existe une explication plus détaillée concernant la moitié de la distance, cette page .

Je ne suis pas sûr de la technologie que vous utilisez, mais Struts fournit une prise en charge au niveau de la structure pour ce modèle. Voir l'exemple ici

Autres conseils

Placez un identifiant unique sur la page dans un champ caché. N'accepter qu'une seule réponse avec un identifiant unique donné.

Il semble que vous utilisiez peut-être une requête GET pour modifier l’état du serveur (bien que ce ne soit pas nécessairement le cas). Bien que cela puisse ne pas convenir à votre situation, il convient de préciser que vous devez envisager de convertir le lien en un formulaire POST.

Il semble que vous ayez déjà répondu à votre propre question ici; # 1 semble être la seule option viable.

Sinon, vous devez vraiment effectuer les trois étapes: l'intégrité des données doit être gérée au niveau de la base de données, mais des vérifications supplémentaires (telles que la transaction explicite) dans le code afin d'éviter les allers-retours à la base de données pourraient être bonnes pour les performances. / p>

REF Vous devez implémenter le modèle de jeton Synchronizer.

Ceci est pour Javascript / HTML pas JAVA

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top