Comment délibérément verrouiller un MySQL en ligne de sorte que même SÉLECTIONNER retournera un message d'erreur?
Je suis en train d'utiliser MySQL en ligne de verrouillage pour émuler un MuteEx sur une ligne. Disons que mon tableau a 2 colonnes, un id et un champ de texte, et trois entrées (1,a), (2,b) et (3,c).
SELECT * from table; serait le retour de ces résultats.
Je peux verrouiller une ligne spécifique de la voie normale.
START TRANSACTION;
BEGIN;
SELECT * FROM table WHERE id = '2' FOR UPDATE;
Toutefois, si à partir d'une deuxième connexion je SELECT * from table. Il serait de retour tous les 3 résultats. Est-il un moyen pour le verrouillage de niveau ligne pour éviter toute SÉLECTIONNEZ voir/à l'aide d'une ligne qui est verrouillée? Fondamentalement, je suis en train d'essayer d'empêcher une personne d'utiliser la ligne qui est actuellement utilisée/manipulé, ou même l'affichage de la ligne que ses données (puisque c'est d'être utilisés ou manipulés) ne peut pas faire confiance à être précis au moment de SÉLECTIONNER.
OriginalL'auteur bahhumbug | 2010-01-12
Vous devez vous connecter pour publier un commentaire.
Si vous définissez le niveau d'isolation de transaction à
SERIALIZABLE
,InnoDB
wil implicity ajouterLOCK IN SHARE MODE
à tousSELECT
consolidés.Ce mode de conflits avec les verrous placés par
SELECT FOR UPDATE
et laSELECT
s de verrouillage.Noter, cependant, que
InnoDB
peut se bloquer plus de lignes que de satisfaire laWHERE
condition. C'est parce qu'il verrouille toutes les lignes numérisés, et pas seulement ceux appariés.Dire, vous avez un indice sur
col1
et cette requête:utilise cet indice.
Bloquer tous enregistrements avec
col1 = 1
, même ceux aveccol2 <> 2
OriginalL'auteur Quassnoi
Vous avez besoin d'un
LOCK IN SHARE MODE
. En l'utilisant avec SÉLECTIONNEZ garantit que personne n'est le verrouillage de toutes les lignes avecFOR UPDATE
.par exemple
Client ne
SELECT * FROM table WHERE type=2 FOR UPDATE
Client B ne
SELECT * FROM table LOCK IN SHARE MODE
et se bloque iciClient Un écrit/Insertions/Mises à jour quelque chose d'un
COMMIT
Client B maintenant, non gèle et reprend le traitement
OriginalL'auteur servermanfail
En fait, les données de ligne peut faire confiance même lorsque vous êtes en les manipulant.
Si vous démarrez une transaction à partir d'une connexion, d'autres connexions ne pas voir l'un de vos modifications jusqu'à ce que vous valider la transaction.
OriginalL'auteur Timo Stamm
Je ne sais pas si il est à l'origine d'un blocage du mécanisme spécifique pour le faire, mais mon premier sens inné serait de donner à la table une colonne de statut (par exemple,
locked
) et en le définissant à1
lors de la fermeture de la ligne. Unselect
sensible de ce serait alors toujours ajouter unWHERE locked != '1'
condition à toute requête.Sur une note de côté, je ne sais pas ce que vous faites, mais n'est-ce pas une tâche qui devrait être fait à un niveau ou deux au-dessus du moteur de base de données?
OriginalL'auteur Pekka 웃