LOCK TABLES Nom_table [AS alias] {READ | [LOW_PRIORITY] WRITE}
[, Nom_table {READ | [LOW_PRIORITY] WRITE} ...]
...
UNLOCK TABLES
LOCK TABLES
verrouille une table dans le thread courant. UNLOCK TABLES
ouvre tous les verrous posé par le thread courant. Toutes les tables verrouillé par un thread sont automatiquement déverrouillée quand le thread émet un autre LOCK TABLES
, ou à la fin de la connexion au serveur.
Si un thread obtiens le verrou de lecture (READ
) sur une table, le thread (et tous les autres threads) ne peut que lire dans la table. Si un thread obtiens e verrou de lecture (READ
) sur une table, le thread qui a le verrous est le seul à pouvoir lire ou écrire dans la table.
Les autres threads attendent (sans limite) que le verrous se libère.
Le verrous d'écriture a une priorité supérieure au verrou de lecture, afin que les processus de mise à jour puisse se faire dès que possible. Cela signifie que si un thread obtiens un verrou de lecture, et qu'un autre thread obtiens un verrou d'écriture, alors le thread au verrou de lecture devra attendre la libération du verrou d'écriture. Il est possible d'utiliser des verrous d'écriture de basse priorité (LOW_PRIORITY WRITE
), mais il faut être sur qu'il y aura un moment ou aucun thread ne sera en train de lire la table.
Lors de l'utilisation de la commande LOCK TABLES
, il faut verrouiller toutes les tables qui vont être utilisées. Si il y a des alias dans une requête, il faut aussi avoir les verrous pour les alias! Cette politique assure que la table ne se verrouille jamais, sans pouvoir être déverrouillée.
Il ne faut jamais verrouiller une table qui va accepter une insertion reportée (INSERT DELAYED)
. Car, dans ce cas, l'insertion sera faite dans un autre thread, qui n'aura pas le verrou.
Généralement, il n'y a pas besoin de verrouiller les tables, car les mise à jour UPDATE
sont atomiques : aucun autre thread ne peut interférer avec la commande en cours d'éxécution. Il y a toutes fois, quelques cas où il est bon de verrouiller une table :
- Si un grand nombre d'opération vont être menée sur un bon nombre de table, il est plus rapide de verrouiller les tables utilisées. L'inconvénient, bien sur, est qu'aucun autre thread ne pourra accèder aux informations, ni les modifier.
- MySQL ne supporte pas d'environnement transactionnel, donc il faut absolument verrouiller une table, pour s'assurer qu'au autre thread n'intervient entre une commande
SELECT
et une commande UPDATE
. L'exemple ci-dessous montre comment exécuter une transaction :
-
-
mysql> LOCK TABLES trans READ, customer WRITE;
mysql> select sum(value) from trans where customer_id= some_id;
mysql> update customer set total_value=sum_from_previous_statement
where customer_id=some_id;
mysql> UNLOCK TABLES;
Sans la commande LOCK TABLES
, il se peut qu'un autre thread insère une nouvelle ligne dans la table trans
entre les deux commandes SELECT
et UPDATE
.
En utilisant des modifications incrémentales (UPDATE customer SET value=value+new_value
) ou avec la commande LAST_INSERT_ID()
, on peut généralement éviter l'utilisation des LOCK TABLES
.
Il est aussi possible de résoudre quelques cas en utilisant les verrous utilisateurs GET_LOCK()
et RELEASE_LOCK()
. Ces verrous sont sauvés dans une table du serveur, et programmé avec pthread_mutex_lock()
et pthread_mutex_unlock()
pour plus de rapidité.n Miscellaneous functions
.
10.11 Comment MySQL verrouille les tables.