Mysql
 sql >> Database >  >> RDS >> Mysql

Evita il deadlock ordinando esplicitamente

Sebbene tu possa farlo tramite straight_join, puoi anche ottenere esplicitamente i blocchi sulle righe desiderate duplicando il select ...for update su quella che vuoi ottenere per prima.

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;

Poiché il blocco viene eseguito in più passaggi, è possibile modificare le voci nella tabella "colori" tra quando imposti la tabella temporanea e quando finisci di ottenere i blocchi sulle due tabelle.

Potrebbe andar bene per te (cioè se desideri modificare solo le voci esistenti, all'inizio della transazione), ma potrebbe causare piccoli bug se non è quello che vuoi.