質問のタイトルに対する直接の答えは「いいえ」です。
SELECTクエリは、クラスター化インデックスとも呼ばれるgen_clust_indexに対してロックを実行できます。
以下は、これらの質問をした人である@RedBlueThingで積極的に調べた3つのDBA Stack Exchanges 質問です。@RedBlueThingは、彼の質問に対する回避策を見つけました。
質問の全体像を保つために、これらの回答をよく見ると(あまり深く見てはいけません。自分の複雑な回答を見てもめまいがします)、SELECTクエリがデータをロックできることがすぐにわかります。
また、特定の行をオンデマンドでロックできるSELECTの特殊なケースもあります。
UPDATE 2011-08-08 16:49 EDT
バリエーションに関する質問:「InnoDBデッドロック例外がSELECTによってスローされる可能性がありますか?」これに対する答えは、特定の条件下では[はい]になります。その状態は何ですか?エラーの結果として単一のSQLステートメントのみがロールバックされた場合、ステートメントによって設定されたロックの一部が保持される可能性があります。これは、InnoDBが行ロックを、どのロックがどのステートメントによって設定されたのか後で確認できないような形式で格納するために発生します。
そのステートメントに基づくと、これを引き起こすイベントのシーケンスは理論的には次のようになります。
- SQLは単一行を更新しますが、エラーを生成します
- UPDATEは1行のロールバックを引き起こします
- 行に残っているロックがあります
個人的には、その最後の発言は私を怖がらせます。MySQLがこの癖をすべての人に知らせるのは良かったでしょう。しかし、そのステートメントはMySQLドキュメントからのものです。(そうそう、OracleはInnoDBを所有している)
UPDATE 2015-09-22 18:40 EST
その年の初めに、Perconaが、眠っている接続の背後に隠れているこれらの厄介なロックを見つけるためのクールなNagiosチェックがあることを知りました。あとは、そのリンクからコードを実行するだけです。
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;
これはMySQL 5.5以降でのみ機能します。MySQL 5.1以前を使用している場合、ロックを解放するには、スリープ状態のすべての接続を強制終了する必要があります。