sql >> Base de Datos >  >> RDS >> Mysql

Evite el punto muerto ordenando explícitamente

Aunque puede hacerlo a través de straight_join, también puede obtener explícitamente los bloqueos en las filas que desea duplicando la selección ... para actualizar la que desea obtener primero.

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;

Como el bloqueo se realiza en varios pasos, sería posible modificar las entradas en la tabla 'colores' entre el momento en que configura la tabla temporal y el momento en que termina de obtener los bloqueos en las dos tablas.

Eso puede estar bien para usted (es decir, si solo desea modificar las entradas existentes, cuando comienza la transacción), pero podría causar errores sutiles si no es lo que desea.