La réponse directe au titre de votre question est Non.
Les requêtes SELECT peuvent effectuer des verrous sur gen_clust_index , alias l'index clusterisé.
Voici trois questions sur les échanges de piles DBA que j'ai examinées avec agressivité avec @RedBlueThing , la personne qui a posé ces questions. @RedBlueThing a trouvé des solutions à ses questions.
Juste pour garder votre question en perspective, lorsque vous regardez ces réponses (ne regardez pas trop profondément, même si j'ai le vertige en regardant mes propres réponses alambiquées), il devrait être rapidement évident que les requêtes SELECT peuvent verrouiller les données.
Vous avez également des cas spéciaux de SELECT où vous pouvez verrouiller des lignes spécifiques à la demande .
MISE À JOUR 2011-08-08 16:49 EDT
Vous avez posé la question de variation: "Les exceptions de blocage InnoDB vont-elles être levées par SELECT"? La réponse à cette question peut être Oui sous certaines conditions. Quelle est cette condition? Si une seule instruction SQL est annulée à la suite d'une erreur, certains des verrous définis par l'instruction peuvent être conservés. Cela se produit car InnoDB stocke les verrous de ligne dans un format tel qu'il ne peut pas savoir par la suite quel verrou a été défini par quelle instruction .
Sur la base de cette déclaration, les séquences d'événements à l'origine de cela pourraient théoriquement être les suivantes:
- Votre SQL UPDATEs une seule ligne mais génère une erreur
- La MISE À JOUR provoque une restauration de la première ligne
- La rangée a une serrure persistante
Personnellement, cette dernière déclaration me fait peur. Il aurait été bien que MySQL informe tout le monde de cette bizarrerie. Pourtant, cette déclaration provient de la documentation MySQL. (Oh oui, Oracle possède InnoDB)
MISE À JOUR 2015-09-22 18:40 EST
Plus tôt dans l'année, j'ai appris que Percona avait un bon chèque Nagios pour trouver ces serrures embêtantes cachées derrière des connexions endormies. Il ne vous reste plus qu'à exécuter le code à partir de ce lien:
SELECT COALESCE(MAX(IF(p.command = 'Sleep', p.time, 0)), 0) AS idle_in_trx
FROM INFORMATION_SCHEMA.INNODB_LOCK_WAITS AS w
INNER JOIN INFORMATION_SCHEMA.INNODB_TRX AS b ON b.trx_id = w.blocking_trx_id
INNER JOIN INFORMATION_SCHEMA.INNODB_TRX AS r ON r.trx_id = w.requesting_trx_id
LEFT JOIN INFORMATION_SCHEMA.PROCESSLIST AS p ON p.id = b.trx_mysql_thread_id;
Cela ne fonctionnera que pour MySQL 5.5+. Si vous avez MySQL 5.1 ou une version antérieure, vous devez tuer toutes les connexions en veille pour libérer les verrous.