6
votes

Sélectionnez ... pour la mise à jour et max ()

DO SELECT ... pour la mise à jour code> dans cette requête des lignes de verrouillage de la requête dans cette table?

La table est en Innodb et la requête est dans la transaction intérieure P>

select max(id) from table1 FOR UPDATE


2 commentaires

Qu'est-ce qui vous fait penser que ça ne les verrouille pas?


Et quel est ce résultat? Peut-être que vous interprétez le problème


5 Réponses :


2
votes

Sélectionnez ... pour mettre à jour bloque d'autres sessions à partir de Sélectionnez ... verrouillage en mode partage

Utilisez à la place Sélectionnez ... Verrouillage en mode de partage QUI

Définit un verrou de mode partagé sur les rangées lire. Un verrouillage de mode partagé permet à d'autres sessions pour lire les rangées mais pas pour modifier-les. Les rangées lues sont la Dernière disponible, donc s'ils appartiennent à une autre transaction qui n'a pas encore engagé, les blocs de lecture jusqu'à ce que la transaction se termine.

voir dans le docs . < / p>


0 commentaires

2
votes

Peut-être cela fonctionnerait-il? :

select id from table where id IN (select max(id) from table1) FOR UPDATE


0 commentaires

-2
votes

comme dans la documentation Oracle Cette clause est soumise aux restrictions suivantes: Vous ne pouvez pas spécifier cette clause avec les autres constructions suivantes: l'opérateur distinct, l'expression du curseur, les opérateurs de définir, le groupe_by__clause ou les fonctions d'agrégat.


0 commentaires

2
votes

Sélectionnez max (ID) à partir de table1 pour la mise à jour - ne verrouille aucune ligne de lignes car elle ne change pas de lignes. Les informations requises sont extraites à partir de l'indice de table.

Ceci est affiché si vous préparez un décrivez à la requête, affichant: xxx

< Code> Sélectionnez ID à partir de table1 où id = (Sélectionnez max (ID) à partir de table1) pour la mise à jour - verrouille cette ligne qui correspond à max (id) Parce que vous récupérez explicitement cette ligne.

Sélectionnez ID à partir de table1 Commande par ID DE LA LIMITE 1 POUR LA MISE À JOUR - Verrouillez-la toutes les lignes et récupéreront Max (id) à l'aide d'une combinaison de commander par et limite 1 .

Ceci est à nouveau expliqué par un Décrire requête.


2 commentaires

Sûrement pour l'exactitude mySQL doit faire le verrouillage (lorsque ID est indexé probablement qu'il doit contenir un verrou sur cet enregistrement)


La documentation MySQL stipule que "Sélectionner des tables optimisées" signifie que "il n'est pas nécessaire de lire des tableaux lors de l'exécution de la requête", au moins pour 5,5, 5,6, 5.7: dev.mysql.com/doc/refman/5.5/fr/Explain-Output.html dev.mysql.com/doc/refman/5.6/fr/Explain-Output.html < / a> dev.mysql.com/doc/refman/5.7 /en/explain-Output.html



1
votes

J'ai trébuché sur cela aussi et j'ai testé ce cas. xxx

thread 1: xxx

thread 2: xxx

thread 1: xxx

thread 2: xxx

Il apparaît InnoDB ne verrouille pas l'écart lorsque vous utilisez la fonction de groupe, verrouille simplement les enregistrements existants. Sans filetage de la fonction de groupe 2 renvoie 2 rangées, y compris une nouvelle, comme prévu.


0 commentaires