Recherche…


Syntaxe

  • LOCK TABLES nom_table [READ | ÉCRIRE]; // Lock Table

  • DÉVERROUILLEZ LES TABLES; // Déverrouiller les tables

Remarques

Le verrouillage est utilisé pour résoudre les problèmes de concurrence. Le verrouillage est requis uniquement lors de l'exécution d'une transaction, qui lit d'abord une valeur à partir d'une base de données et, plus tard, écrit cette valeur dans la base de données. Les verrous ne sont jamais requis pour les opérations d'insertion, de mise à jour ou de suppression autonomes.

Il existe deux types de serrures disponibles

READ LOCK - lorsqu'un utilisateur lit uniquement depuis une table.

WRITE LOCK - lorsqu'un utilisateur lit et écrit à la fois un tableau.

Lorsqu'un utilisateur détient un WRITE LOCK sur une table, aucun autre utilisateur ne peut lire ou écrire sur cette table. Lorsqu'un utilisateur détient un READ LOCK sur une table, d'autres utilisateurs peuvent également lire ou maintenir un READ LOCK , mais aucun utilisateur ne peut écrire ou maintenir un WRITE LOCK sur cette table.

Si le moteur de stockage par défaut est InnoDB, MySQL utilise automatiquement le verrouillage au niveau des lignes afin que plusieurs transactions puissent utiliser la même table simultanément pour la lecture et l'écriture, sans se faire mutuellement attendre.

Pour tous les moteurs de stockage autres qu'InnoDB, MySQL utilise le verrouillage de table.

Pour plus de détails sur le verrouillage de la table Voir ici

Mysql Serrures

Les verrous de table peuvent être un outil important pour ENGINE=MyISAM , mais sont rarement utiles pour ENGINE=InnoDB . Si vous êtes tenté d'utiliser des verrous de table avec InnoDB, vous devez repenser la façon dont vous travaillez avec les transactions.

MySQL permet aux sessions client d'acquérir explicitement des verrous de table dans le but de coopérer avec d'autres sessions pour accéder aux tables ou d'empêcher d'autres sessions de modifier des tables pendant les périodes où une session nécessite un accès exclusif à ces dernières. Une session peut acquérir ou libérer des verrous uniquement pour elle-même. Une session ne peut pas acquérir de verrous pour une autre session ou libérer des verrous détenus par une autre session.

Les verrous peuvent être utilisés pour émuler des transactions ou pour accélérer la mise à jour des tableaux. Ceci est expliqué plus en détail plus loin dans cette section.

Commande: LOCK TABLES table_name READ|WRITE;

vous ne pouvez affecter que le type de verrou à une seule table;

Exemple (READ LOCK):

LOCK TABLES table_name READ;

Exemple (WRITE LOCK):

LOCK TABLES table_name WRITE;

Pour voir que le verrou est appliqué ou non, utilisez la commande suivante

SHOW OPEN TABLES;

Pour vider / supprimer tous les verrous, utilisez la commande suivante:

UNLOCK TABLES;

EXEMPLE:

LOCK TABLES products WRITE:  
INSERT INTO products(id,product_name) SELECT id,old_product_name FROM old_products;
UNLOCK TABLES;

Par exemple, toute connexion externe ne peut écrire aucune donnée dans la table des produits avant de déverrouiller le produit de la table

EXEMPLE:

LOCK TABLES products READ:  
INSERT INTO products(id,product_name) SELECT id,old_product_name FROM old_products;
UNLOCK TABLES;

Par exemple, toute connexion externe ne peut lire aucune donnée de la table des produits avant de déverrouiller le produit de la table

Verrouillage au niveau des lignes

Si les tables utilisent InnoDB, MySQL utilise automatiquement le verrouillage au niveau des lignes afin que plusieurs transactions puissent utiliser la même table simultanément pour la lecture et l'écriture, sans se faire mutuellement attendre.

Si deux transactions tentent de modifier la même ligne et que les deux utilisent le verrouillage au niveau des lignes, l'une des transactions attend que l'autre se termine.

Le verrouillage au niveau des lignes peut également être obtenu en utilisant l' SELECT ... FOR UPDATE pour chaque ligne à modifier.

Considérons deux connexions pour expliquer le verrouillage au niveau des lignes en détail

Connexion 1

START TRANSACTION;
SELECT ledgerAmount FROM accDetails WHERE id = 1 FOR UPDATE;

Dans la connexion 1, le verrouillage de niveau de ligne est obtenu par l' SELECT ... FOR UPDATE .

Connexion 2

UPDATE accDetails SET ledgerAmount = ledgerAmount + 500 WHERE id=1;

Lorsque quelqu'un essaie de mettre à jour la même ligne dans la connexion 2, cela attendra que la connexion 1 termine la transaction ou le message d'erreur sera affiché en fonction du paramètre innodb_lock_wait_timeout , qui par défaut est 50 secondes.

Error Code: 1205. Lock wait timeout exceeded; try restarting transaction

Pour afficher les détails de ce verrou, exécutez SHOW ENGINE INNODB STATUS

---TRANSACTION 1973004, ACTIVE 7 sec updating
mysql tables in use 1, locked 1
LOCK WAIT 2 lock struct(s), heap size 360, 1 row lock(s)
MySQL thread id 4, OS thread handle 0x7f996beac700, query id 30 localhost root update
UPDATE accDetails SET ledgerAmount = ledgerAmount + 500 WHERE id=1
------- TRX HAS BEEN WAITING 7 SEC FOR THIS LOCK TO BE GRANTED:

Connexion 2

UPDATE accDetails SET ledgerAmount = ledgerAmount + 250 WHERE id=2;
1 row(s) affected

Mais lors de la mise à jour d'une autre ligne de la connexion 2 sera exécutée sans aucune erreur.

Connexion 1

UPDATE accDetails SET ledgerAmount = ledgerAmount + 750 WHERE id=1;
COMMIT;
1 row(s) affected

Maintenant, le verrouillage de ligne est libéré, car la transaction est validée dans la connexion 1.

Connexion 2

UPDATE accDetails SET ledgerAmount = ledgerAmount + 500 WHERE id=1;
1 row(s) affected

La mise à jour est exécutée sans aucune erreur dans la connexion 2 après le verrouillage de la ligne de la connexion 1 en terminant la transaction.



Modified text is an extract of the original Stack Overflow Documentation
Sous licence CC BY-SA 3.0
Non affilié à Stack Overflow