Comment utiliser Redis serrure pour résoudre les problèmes de haute simultanéité

Source : Internet
Auteur : utilisateur
Le problème de haute simultanéité est un problème que nous pouvons rencontrer souvent, alors, comment résoudre le problème de haute simultanéité ? Le contenu de cet article consiste à utiliser le Redis serrure à résoudre des problèmes de haute simultanéité, jetez un oeil à son ensemble.

Ici, nous utilisons principalement la commande SETNX de Redis à gérer haute simultanéité.

SETNX possède deux paramètres. Le premier paramètre représente une clé. Le deuxième paramètre représente une valeur. Si la clé actuelle n’existe pas, la clé actuelle est insérée et le second paramètre est fait comme une valeur. Retourne 1. Si la clé actuelle existe, 0 est retourné.

Créer une table de l’inventaire

CREATE TABLE `storage` (  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,  `number` int(11) DEFAULT NULL,  PRIMARY KEY (`id`)) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=latin1

La valeur de l’inventaire initial à 10

Créer une table de commandes

CREATE TABLE `order` (  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,  `number` int(11) DEFAULT NULL,  PRIMARY KEY (`id`)) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=latin1

Quand le test n’a pas besoin un verrou,

$pdo = new PDO('mysql:host=127.0.0.1;dbname=test', 'root', 'root');$sql="select `number` from  storage where id=1 limit 1";$res = $pdo->query($sql)->fetch();$number = $res['number'];if($number>0){    $sql ="insert into `order`  VALUES (null,$number)";    $order_id = $pdo->query($sql);    if($order_id)    {        $sql="update storage set `number`=`number`-1 WHERE id=1";        $pdo->query($sql);    }}

Le test de AB simule la simultanéité et conclut que l’inventaire est correcte.

mysql> select * from storage;+----+--------+| id | number |+----+--------+|  1 |      0 |+----+--------+1 row in set (0.00 sec)

En regardant le tableau de commande

mysql> select * from `order`;+----+--------+| id | number |+----+--------+|  1 |     10 ||  2 |     10 ||  3 |      9 ||  4 |      7 ||  5 |      6 ||  6 |      5 ||  7 |      5 ||  8 |      5 ||  9 |      4 || 10 |      1 |+----+--------+10 rows in set (0.00 sec)

Il a été constaté que l’existence de plusieurs ordres était les mêmes données de l’inventaire pour l’opération, qui pourrait donner lieu à des situations de survente.

Modifier le code pour ajouter Redis verrou pour le contrôle de données

≪ ? Php / ** * créée par PhpStorm.    * Utilisateur : daisc * DATE : 2018/7/23 * temps : 14:45 * / class Lock {private static $_instance ;    Private $_redis ;        Private Function __construct () {$this -> _redis = new Redis () ;    $This -> _redis -> connect (« 127.0.0.1 ») ; Public static function getInstance () {si (self :: $_instance instanceof soi) {return auto        :: $_Instance ;    } Return self :: $_instance = new (libre) ;     } / ** * @Function lock * @param $key nom du verrou * @param $expTime délai d’Expiration * / public function set ($key, $expTime)        {//Initial $isLock de verrouillage = $this - > _redis -> setnx ($key, Time () + $expTime) ;        Si ($isLock) {return true ; } Else {//Lock a échoué dans l’affaire. Détermine si la serrure existe déjà et, si la serrure existe, la coupe a expiré, puis supprime le verrou.            Pour re-verrouiller $val = $this - > _redis -> get ($key) ;            Si ($val $val < fois ()) {$this -> del ($key) ;        Return $this -> _redis -> setnx ($key, Time () + $expTime) ;    }} / ** * @Param $key déverrouiller * / public Function del ($key) {$this -> _redis -> del ($key) ; }} $Pdo = new PDO (' Mysql:host = 127.0.0.1 ; dbname = test ', « root », « root ») ; $lockObj = Lock::getinstance () ; //is jugé capable de verrouiller correctement si ($    Verrou = $lockObj -> set (« stockage »,) {$sql = « sélectionnez ", » de stockage où id = 1 limite 1 « ;    $Res = $pdo - > query ($sql) -> fetch () ;    $Number = $res [' No '] ;        Si (> 0) {$sql = « insert INTO « commande » VALUES (null,) » ;        $Order _id = $pdo -> query ($sql) ;            Si (er _id) {$sql = « mise à jour d’ensemble de stockage «, » 1 où id = 1 » ;        $Pdo -> query ($sql) ; {}} //Unlock $lockObj -> del (« stockage ») ;} Else {//Lock n’a pas effectué autres opérations avec succès. }

Procédez à nouveauabTest, afficher les résultats de test

mysql> select * from `order`;+----+--------+| id | number |+----+--------+|  1 |     10 ||  2 |      9 ||  3 |      8 ||  4 |      7 ||  5 |      6 ||  6 |      5 ||  7 |      4 ||  8 |      3 ||  9 |      2 || 10 |      1 |+----+--------+10 rows in set (0.00 sec)

Constaté que la table order n’opérait pas les mêmes données de l’inventaire. Par conséquent, l’utilisation de verrous Redis peut gérer efficacement haute simultanéité.

Ici dans la serrure quand en fait ne peut pas besoin de juger l’expiration le temps, ici nous afin d’éviter la cause du blocage, donc ajouter un arrêt de temps d’expiration. Activement supprimer le verrou quand il expire.

Nous contacter

Le contenu de cette page provient d'Internet et ne reflète pas l'opinion d'Alibaba Cloud ; les produits et services mentionnés sur cette page n'ont aucune relation avec Alibaba Cloud. Si le contenu de la page vous semble problématique, veuillez nous écrire un courriel, nous traiterons le problème dans les 5 jours suivant la réception de votre message.

Si vous constatez des cas de plagiat de la part de la communauté, veuillez envoyer un courriel à : info-contact@alibabacloud.com et fournir des preuves pertinentes. Un membre de notre équipe vous contactera dans les 5 jours ouvrables.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.