8
votes

Comment verrouiller délibérément une ligne mysql telle que même Select retournera une erreur?

J'essaie d'utiliser le verrouillage de la rangée MySQL pour émuler essentiellement un MontEx sur une rangée. Disons que ma table a 2 colonnes, un identifiant et un champ de texte et trois entrées (1, A) (2, B) et (3, C). Sélectionnez * à partir de la table; retournerait ces résultats. Je peux verrouiller une ligne spécifique la voie normale. xxx

Toutefois, si d'une seconde connexion, je devais sélectionner * à partir de la table. Il retournerait tous les 3 résultats. Existe-t-il un moyen de verrouillage de niveau de ligne pour empêcher fondamentalement n'importe quel choix de voir / à l'aide d'une ligne verrouillée? Fondamentalement, j'essaie d'empêcher toute personne d'utiliser la ligne qui est actuellement utilisée / manipulée, ou même la visualisation de la ligne comme ses données (car elle est utilisée / manipulée) ne peut pas être confiée pour être précise au moment d'une sélection .


1 commentaires

Peut-être pas ce que vous (ou i) veulent entendre, mais il semble que si le deuxième sélecteur utilise également SELECT ... pour la mise à jour , il va attendre que le verrouillage initial soit libéré.


4 Réponses :


0
votes

Je ne sais pas s'il y a un mécanisme spécifique de verrouillage natif, mais mon premier instant serait de donner à la table une colonne d'état (par exemple, verrouillé ) et de la définition que sur < Code> 1 lors du verrouillage de la ligne. Un SELECT sensible de cela permettrait toujours d'ajouter un où verrouillé! = '1' condition à n'importe quelle requête.

Sur une note latérale, je ne sais pas ce que vous faites, mais n'est-ce pas une tâche qui devrait être effectuée de niveau ou deux au-dessus du moteur de base de données?


1 commentaires

J'étais juste curieux de savoir si c'était possible ou non de la base de données. Comme ma méthode actuelle se sentait un peu maladroite. Le projet est multithreadé et chaque thread doit sélectionner des travaux à partir d'une base de données (le travail est ajouté de plusieurs zones constamment), cependant, pas de deux threads ne devraient tenter le même travail en même temps, alors ma solution actuelle était donc un MontEx sur Une fonction qui a sélectionné le travail disponible, puis a mis à jour ces lignes spécifiquement pour dire qu'elles sont travaillées avant de libérer le mutex. Je suppose que je fais déjà la meilleure solution.



6
votes

Si vous définissez le niveau d'isolation de transaction sur Serializable , innodb WIL Implication APPEND verrouillage en mode partage à tous Sélectionnez Décloses.

Ce mode est en conflit avec les verrous placés par Sélectionnez pour mettre à jour et le SELECT S Verrouiller.

note, cependant, que innodb peut verrouiller plus de lignes que de satisfaire le condition. C'est parce qu'il verrouille toutes les lignes scannées , non seulement celles assorties .

disent, vous avez un index sur col1 et cette requête: xxx

utilise cet index.

ceci verrouille tous les enregistrements avec col1 = 1 < / code>, même ceux avec col2 <> 2


0 commentaires

2
votes

En réalité, les données de la ligne peuvent être approuvées, même si vous le manipulez.

Si vous démarrez une transaction à partir d'une connexion, d'autres connexions ne verront aucun de vos modifications tant que vous ne commetez pas la transaction.


0 commentaires

5
votes

Vous avez besoin d'un verrouillage en mode partage . Utilisant avec Sélectionner des garanties, personne d'autre ne verrouille de lignes avec pour la mise à jour .

E.g.

client A fait Sélectionnez * à partir de la table où Type = 2 pour la mise à jour

Client B fait SELECT * à partir du verrouillage de table en mode partage et bloque ici

client A écrit / insère / met à jour quelque chose que quelque chose est alors un commettre

client B désormais désagréable et reprend le traitement


0 commentaires