Straight_join を介して行うこともできますが、最初に取得したい行の select ...for update を複製することで、必要な行のロックを明示的に取得することもできます。
CREATE TEMPORARY TABLE colorsToUpdate (
colorID BIGINT(20) NOT NULL,
modelID BIGINT(20) NOT NULL
);
insert into colorsToUpdate ( colorID, modelID)
SELECT id, model_id
FROM colors
where id in (101, 105, 106);
#This will try to acquire lock on models
select m.* from models m
join colorsToUpdate c
on c.modelID = m.id
for UPDATE;
#this will try to get locks on models, and colors.
select m.*, c.*
from colorsToUpdate u
left join models m
on u.modelID = m.id
join colors c
on u.colorID = c.ID
order by m.id asc, c.id asc
for update;
# do your data modification here.
drop table colorsToUpdate;
ロックは複数のステップで行われるため、一時テーブルを設定してから 2 つのテーブルのロックを取得し終えるまでの間に、テーブル 'colors' のエントリが変更される可能性があります。
これで問題ないかもしれませんが (つまり、トランザクションの開始時に既存のエントリを変更するだけの場合)、それが望ましくない場合は微妙なバグが発生する可能性があります。