MySQl : LOCK TABLE en écriture mais pas en lecture

Eléphant du PHP | 245 Messages

23 sept. 2011, 16:17

salut, j'ai une question sur l'utilisation de lock tables.
Pour l'utilisation de lock tables :

Je veux locker 2 tables le temps d'executer un script :
LOCK t1 WRITE, t2 WRITE;
UPDATE t1 set col1='test' where id=1;
INSERT into t2 (id_t1) value(1);
UNLOCK tables;
Je ne veux pas qu'un autre thread vienne modifier une des deux tables (insert, delete, update) entre l'éxecution des 2 requêtes.
Donc mon script marche.
Mais ça ne me dérangerait pas que d'autres thread puissent accéder à t1 en lecture seulement.

Je n'ai pas trouver d'option le permettant, donc j'utilise WRITE à défaut de trouver mieux.
Y-a-til des directives qui correspondraient à mes attentes?

Avatar du membre
Modérateur PHPfrance
Modérateur PHPfrance | 8758 Messages

25 sept. 2011, 00:12

salut,

tu ne peux pas utiliser un read local ? => http://dev.mysql.com/doc/refman/5.0/fr/lock-tables.html

ne peux tu pas simplement utiliser une transaction ?

problème possible en utilisant lock : http://dev.mysql.com/doc/refman/5.0/fr/ ... cking.html


@+
Il en faut peu pour être heureux ......

Eléphant du PHP | 245 Messages

26 sept. 2011, 11:42

Merci Moogli, la doc sur les problèmes de LOCKAGE est intéressante.

En fait j'ai simplifié mes requêtes SQL, mais il y a aussi une transaction
LOCK t1 WRITE, t2 WRITE;
SET AUTOCOMMIT =0;
START TRANSACTION;
UPDATE t1 SET col1='test' WHERE id=1;
INSERT INTO t2 (id_t1) value(1);
COMMIT; -- ou ROLLBACK;
UNLOCK TABLES;
Lorsque j'instancie un objet, il me faut modifier 2 tables. La transaction me permet de valider les requêtes sur les 2 tables ou de les invalider toutes les 2 en cas de problème.
Elle ne concerne qu'un objet.

Après, non seulement, je veux que cela se passe bien pour un objet, mais je ne veux pas qu'un autre objet s'instancie au même moment et me fasse un truc du genre
UPDATE t1 SET col1='test' WHERE id=1;
UPDATE t1 SET col1='test' WHERE id=2;
INSERT INTO t2 (id_t1) value(1);
INSERT INTO t2 (id_t1) value(2);
(même si la cohérence des données est sauvegardée pour chaque objet grâce à une transaction)

Je veux forcément un truc du gene :
UPDATE t1 SET col1='test' WHERE id=1;
INSERT INTO t2 (id_t1) value(1);

--puis

UPDATE t1 SET col1='test' WHERE id=2;
INSERT INTO t2 (id_t1) value(2);
Pour cela, je ne vois que le lockage de tables.
Je pensais qu'il existait un moyen simple de locker les tables en écriture mais pas en lecture. READ LOCAL permet exactement le contraire.
J'avoue mon problème est un peu particulier, mais bon...

Avatar du membre
Modérateur PHPfrance
Modérateur PHPfrance | 8758 Messages

26 sept. 2011, 23:32

après relecture effectivement ce n'est pas possible un write impose un read.

ceci dit, normalement la transaction effectue les locks, au pire, sauf problème, tes requêtes devraient être très rapide, et tu ne devrais pas entrer dans les problème de time out.

la je ne vois pas d'autre possibilité :/

@+
Il en faut peu pour être heureux ......

Eléphant du PHP | 245 Messages

29 sept. 2011, 14:52

après relecture effectivement ce n'est pas possible un write impose un read
je viens de me faire la même reflexion ce matin tiens!
du coup, je reste dans ma config et c'est très bien comme ça!
merci en tous cas

Avatar du membre
Modérateur PHPfrance
Modérateur PHPfrance | 8758 Messages

29 sept. 2011, 22:09

de rien :)
Il en faut peu pour être heureux ......

ViPHP
ViPHP | 2577 Messages

03 oct. 2011, 14:59

Bonjour,

J'utilise un compteur de mise à jour sur mes tables.
insert => initialise à 1
update => compteur = compteur + 1

Lors des updates, j'ajoute un test "compteur = $nb" et je vérifie qu'un enregistrement a été mise à jour. Dans le cas contraire, arret de la maj et affichage des donnée modifiée.