前提として、次の通りテーブルを使用する。
CREATE TABLE A ( id INT NOT NULL, no INT NOT NULL, PRIMARY KEY (id, no) ); CREATE TABLE B ( id INT NOT NULL, PRIMARY KEY (id) );
普通に結合すると A と B の両方の行がロックされる。
SELECT * FROM A INNER JOIN B USING (id) WHERE A.id = 1 AND A.no = 1 FOR UPDATE
サブクエリの中で FOR UPDATE すれば、サブクエリの中の A だけがロックされ、外側の B はロックされない。
SELECT * FROM ( SELECT * FROM A WHERE A.id = 1 AND A.no = 1 FOR UPDATE ) X INNER JOIN B USING (id)
逆に、サブクエリの外側で FOR UPDATE した場合、サブクエリの中の A はロックされず、外側の B だけがロックされる。
SELECT * FROM ( SELECT * FROM A WHERE A.id = 1 AND A.no = 1 ) X INNER JOIN B USING (id) FOR UPDATE
相関サブクエリの場合も、サブクエリの外側で FOR UPDATE していれば、外側の A だけがロックされ、内側の B はロックされない。
SELECT * FROM A WHERE A.id = 1 AND A.no = 1 AND EXISTS ( SELECT * FROM B WHERE B.id = A.id ) FOR UPDATE