Maison  >  Article  >  base de données  >  Traitement des transactions à verrouillage à haute concurrence Mysql

Traitement des transactions à verrouillage à haute concurrence Mysql

黄舟
黄舟original
2017-02-06 11:04:182010parcourir

MySQL utilise SELECT … FOR UPDATE pour confirmer avant l'écriture de la transaction

En prenant InnoDB de MySQL comme exemple, le niveau d'isolement Tansaction par défaut est REPEATABLE READ. Il existe deux principaux types de verrous de lecture dans la méthode SELECT :

SELECT … LOCK IN SHARE MODE
SELECT … FOR UPDATE

Ces deux méthodes doivent attendre que d'autres données de transaction soient soumises (Commit) avant de s'exécuter lorsque la SÉLECTION vers la même table de données est en cours. La principale différence est que le VERROUILLAGE EN MODE PARTAGE peut facilement provoquer un blocage lorsqu'une partie souhaite mettre à jour le même formulaire.

Pour faire simple, si vous souhaitez METTRE À JOUR le même formulaire après SELECT, il est préférable d'utiliser SELECT ... UPDATE.

Par exemple : Supposons qu'il y ait une quantité dans le formulaire de produit pour stocker la quantité du produit. Avant d'établir la commande, il faut déterminer si la quantité du produit est suffisante (quantité>0). , puis la quantité est mise à jour à 1.

Pratiques dangereuses :

1    SELECT quantity FROM products WHERE id=3;    
1    UPDATE products SET quantity = 1 WHERE id=3;


Pourquoi est-ce dangereux ?

Il n'y aura peut-être pas de problème dans un petit nombre de cas, mais il y aura certainement des problèmes lors de l'accès à une grande quantité de données.

Si nous devons déduire l'inventaire lorsque la quantité>0, supposons que la quantité lue par le programme dans la première ligne SELECT est 2. Il semble que le nombre soit correct, mais lorsque MySQL se prépare à MISE À JOUR, quelqu'un a peut-être déduit l'inventaire à 0, mais le programme ne le savait pas et a effectué la mauvaise MISE À JOUR.

Par conséquent, un mécanisme de transaction doit être utilisé pour garantir que les données lues et soumises sont correctes.

Nous pouvons donc le tester comme ceci dans MySQL : (Note 1)

1    SET AUTOCOMMIT=0;    
2    BEGIN WORK;    
3    SELECT quantity FROM products WHERE id=3 FOR UPDATE;


À ce moment, les données avec id=3 dans le les données des produits sont verrouillées (Remarque 3) Les autres transactions doivent attendre que cette transaction soit validée avant d'exécuter SELECT * FROM products WHERE id=3 FOR UPDATE (Remarque 2) Cela garantit que le nombre lu par quantité dans les autres transactions est correct.

1    UPDATE products SET quantity = '1' WHERE id=3 ;    
2    COMMIT WORK;

Le commit est écrit dans la base de données et les produits sont déverrouillés.

Remarque 1 : BEGIN/COMMIT est le point de début et de fin de la transaction. Vous pouvez utiliser plus de deux fenêtres de commande MySQL pour observer de manière interactive l'état de verrouillage.

Remarque 2 : Lors d'une transaction, seul SELECT... FOR UPDATE ou LOCK IN SHARE MODE pour les mêmes données attendra la fin des autres transactions avant de s'exécuter. Généralement, SELECT... ne sera pas affecté. par ceci.

Remarque 3 : étant donné qu'InnoDB utilise par défaut le verrouillage au niveau des lignes, veuillez vous référer à cet article pour verrouiller les colonnes de données.

Remarque 4 : essayez de ne pas utiliser l'instruction LOCK TABLES dans les formulaires InnoDB. Si vous devez l'utiliser en dernier recours, veuillez lire les instructions officielles d'utilisation de LOCK TABLES dans InnoDB pour éviter les blocages fréquents dans le système. .

Ce qui précède est le contenu du traitement des transactions de verrouillage à haute concurrence Mysql. Pour plus de contenu connexe, veuillez faire attention au site Web PHP chinois (www.php.cn) !


Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn