2 votes

Gestion de la concurrence dans Laravel

Je crée une API qui interagit avec une base de données d'inventaire MySQL. Nous avons 15 utilisateurs qui peuvent réserver des produits, mettant à jour la base de données de la manière suivante :

  • Diminution de la valeur on-hand et augmentation de la valeur réservée d'un produit.

La table inventaire ressemble à ceci :

id        int
sku       varchar
on-hand   int
reserved  int

Le problème est : Comment gérer la mise à jour de la ligne si 2 utilisateurs essaient de la mettre à jour en même temps ?

La première approche à laquelle je pensais était d'utiliser Transactions:

beginTransaction();

        // SELECT on-hand, reserved from inventory

        // Mettre à jour les valeurs de l'inventaire

        $db->commit();

        return response()->json([ 'success' => 1, 'data' => $data ])
    }

La deuxième consistait à utiliser le verrouillage pessimiste:

sharedLock()

        // Mettre à jour les valeurs de l'inventaire

        return response()->json([ 'success' => 1, 'data' => $data ])
    }

La troisième était de créer un champ updating avec une valeur de zéro. Lors de la sélection des produits à mettre à jour, je vérifierais le champ updating avant de faire quoi que ce soit avec ces lignes. Le problème que je vois ici est que je devrais boucler sur celles avec updating != 0 jusqu'à ce qu'elles deviennent disponibles. Plus de sélections et de mises à jour viennent de cette approche.

Quelle est la meilleure option à prendre? Il peut y avoir plus d'options que celles que j'ai écrites ici.

0voto

Ne pas utiliser de transactions ni de verrouillages pessimistes.

Ne pas non plus utiliser de mise à jour.

Pour la situation de course, il est préférable de revoir votre base de données et de vous débarrasser des mises à jour, utilisez plutôt des insertions. Créez une table pivot pour accomoder la connexion entre les utilisateurs et les produits. Et ne gardez que le premier enregistrement de connexion (où l'identifiant est plus petit) comme le véritable.

Si vous avez besoin d'une explication plus détaillée, voici un exemple :

Disons que 2 utilisateurs se battent pour obtenir le produit. Ils créent tous les deux des enregistrements dans la table pivot, presque simultanément mais quelqu'un doit être le premier, non? Ils valident tous deux de très petites transactions pour persister leurs données. Et ensuite - ils lisent tous deux la table pivot pour vérifier qui a réussi. Le premier enregistrement sera le même pour eux deux, il n'y aura pas de blocage (du moins explicite) dans l'utilisation. Ainsi, un client obtiendra son enregistrement et sera heureux, tandis que l'autre devra recommencer pour obtenir un autre produit.

Et le problème est résolu.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X