7
votes

Comment faire face à des modifications simultanées dans une application Web?

Voici deux flux de travail potentiels que je voudrais effectuer dans une application Web.

Variation 1

  • L'utilisateur envoie la demande
  • Server lit les données
  • Server modifie les données
  • Server enregistre les données modifiées

    Variation 2:

    • L'utilisateur envoie la demande
    • Server lit les données
    • Server envoie des données à l'utilisateur
    • L'utilisateur envoie la demande avec modifications
    • Server enregistre les données modifiées

      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.)

      La situation est hypothétique, mais voici quelques détails de l'endroit où j'aurais probablement besoin de traiter cela dans la pratique:

      • application Web, mais langue non spécifiée
      • potentiellement, à l'aide d'un cadre Web
      • Data Store est une base de données relationnelle SQL
      • La logique impliquée est trop complexe pour exprimer bien dans une requête par exemple. Valeur = Valeur + 1

        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.

        Merci.


0 commentaires

3 Réponses :


0
votes

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.

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.

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" .


4 commentaires

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.



0
votes

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;


0 commentaires

7
votes

Au meilleur de ma connaissance, il n'y a pas de solution générale au problème.

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.

Je connais trois approches fondamentales:

  1. 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?

  2. 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.

    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é.

    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.

    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.

    1. Sur la mise à jour, vérifiez que les champs pertinents dans la base de données correspondent à votre « de la » valeur. Par exemple, supposons que vous travaillez pour une négociation de contrats cabinet d'avocats pour vos clients. Vous disposez d'un écran où un utilisateur peut saisir des notes sur les négociations. Un utilisateur affiche un dossier de contrat. L'utilisateur B fait apparaître le même enregistrement du contrat. Utilisateur A entre qu'il vient de parler à l'autre partie au téléphone et ils sont agréables aux conditions proposées. L'utilisateur B, qui a également essayé d'appeler l'autre partie, entre qu'ils ne répondent pas aux appels téléphoniques et il soupçonne qu'ils sont évasives. clics A Permet d'enregistrer. Est-ce que nous voulons que les commentaires de l'utilisateur B à l'utilisateur A Ecraser de? Probablement pas. Au lieu de cela, nous affichons un message indiquant que les notes ont été modifiées depuis qu'il a lu le dossier, et lui permettant de voir la nouvelle valeur avant de décider de procéder à la sauvegarde, abort, ou entrez quelque chose de différent.

      [Note: le forum est renumérotation automatiquement mes listes numérotées. Je ne sais pas comment passer outre cela.]


0 commentaires