Voici deux flux de travail potentiels que je voudrais effectuer dans une application Web. P>
Variation 1 P>
Variation 2: P>
Dans chacun de ces cas, je me demande: quelles sont les approches standard pour garantir que l'accès simultané à ce service produira des résultats sains? (C'est-à-dire que l'édition de personne ne devient encombré, les valeurs correspondent à une commande des modifications, etc.) p>
La situation est hypothétique, mais voici quelques détails de l'endroit où j'aurais probablement besoin de traiter cela dans la pratique: p>
Je me sens comme si je préférerais ne pas essayer de réinventer la roue ici. Ce sont sûrement des problèmes bien connus avec des solutions bien connues. S'il vous plaît conseiller. P>
Merci. P>
3 Réponses :
Les choses sont simples dans la couche d'application - chaque demande est signifiée par un fil (ou un processus) différent, de sorte que si vous avez d'état dans vos classes de traitement (services), tout est sûr. P>
Les choses sont plus compliquées lorsque vous atteignez la base de données - c'est-à-dire où l'état est tenu. Vous avez besoin Transactions pour vous assurer que tout va bien. P>
Transactions Des propriétés ont un ensemble de propriétés - acide , que "garantissent des transactions de base de données sont traitées de manière fiable" . p>
Merci. Cela fonctionne bien pour la variation 1. Mais quelle est la façon habituelle de traiter cela dans une situation où vous n'avez pas de transactions? par exemple. Myisam de MySQL
Pour clarifier, j'imagine que beaucoup de logiciels de forums devraient faire face à ce type de problème. Pourtant, je vois beaucoup d'entre eux utilisent Myisam, qui n'a pas de transactions. Quelle est leur résolution à cela?
Vous ne pouvez pas traiter de manière fiable avec cela. Le logiciel du forum s'appuie principalement sur des inserts et rarement sur des modifications simultanées, de sorte qu'il ne cause pas de nombreux problèmes
Une chose possible pour Variante 2 serait un champ mis à jour_at pour chaque ligne que vous pourriez souhaiter modifier. Lors de la mise à jour de la ligne, vous enverriez à nouveau cet horodatage sur le serveur pour vous assurer que l'utilisateur n'a pas envoyé sa mise à jour avec des données anciennes (mise à jour_at dans DB Newer que celle de votre demande). Cependant, cela aurait effectivement besoin de transactions pour être vraiment fiables.
Si vous n'avez pas de transactions dans MySQL, vous pouvez utiliser la commande de mise à jour pour vous assurer que les données ne sont pas corrompues.
PreparedStatement query; query = connection.prepareStatement(s); int rows = -1; try { rows = query.executeUpdate(); query.close(); } catch (Exception e) { e.printStackTrace(); } return rows;
Au meilleur de ma connaissance, il n'y a pas de solution générale au problème. P>
La racine du problème est que l'utilisateur peut récupérer des données et regarder sur l'écran pendant longtemps avant de faire une mise à jour et l'enregistrement. P>
Je connais trois approches fondamentales: p>
Lorsque l'utilisateur lit la base de données, verrouiller l'enregistrement, et ne relâchez pas jusqu'à ce que l'utilisateur enregistre des mises à jour. En pratique, cela est follement irréaliste. Que faire si l'utilisateur fait apparaître un écran, puis va déjeuner sans enregistrer? Ou rentre à la maison pour la journée? Ou est tellement frustré d'essayer de mettre à jour ce disque stupide qu'il quitte et ne revient jamais? P> li>
Exprimez vos mises à jour Deltas plutôt que des destinations. Prenons l'exemple classique, supposons que vous avez un système qui enregistre les stocks en inventaire. Chaque fois qu'il ya une vente, vous devez soustraire 1 (ou plus) du compte d'inventaire. P> li> ol>
Alors dire la quantité présente sur la main est 10. Un utilisateur crée une vente. quantité actuelle = 10. L'utilisateur B crée une vente. Il obtient également la quantité actuelle = 10. L'utilisateur A entre que deux unités sont vendues. Nouvelle quantité = 10-2 = 8. Enregistrer. L'utilisateur B entre une unité vendue. Nouvelle quantité = 10 (la valeur qu'il charge) - 1 = 9. Enregistrer. De toute évidence, quelque chose a mal tourné. P>
Solution: Au lieu d'écrire "quantité = 9 jeu d'inventaire de mise à jour où Itemid = 12345", écriture "inventaire de mise à jour la quantité de jeu = quantité-1 où Itemid = 12 345". Ensuite, laissez la base de données file d'attente les mises à jour. Ceci est très différent de la stratégie n ° 1, comme cela a seulement pour verrouiller l'enregistrement de la base de données assez longtemps pour lire, faire la mise à jour et l'écrire. Il ne doit pas attendre que quelqu'un regarde fixement à l'écran. P>
Bien sûr, cela est seulement utilisable pour les changements qui peuvent être exprimées sous la forme d'un delta. Si vous êtes, par exemple, mettre à jour le numéro de téléphone du client, il ne va pas au travail. (Comme, ancien numéro est 555-1234. L'utilisateur A dit de changer à 555-1235. Voilà un changement de +1. L'utilisateur B dit de le changer à 555-1243. Voilà un changement de +9. Donc, le changement total est 10, le nouveau numéro de client est 555-1244. :-)) Mais dans des cas comme ça, « dernier utilisateur de cliquer sur le saisir victoires clés » est probablement le meilleur que vous pouvez faire de toute façon. p>
[Note: le forum est renumérotation automatiquement mes listes numérotées. Je ne sais pas comment passer outre cela.] P>