sql >> Databáze >  >> RDS >> Mysql

Vyhněte se mrtvému ​​zámku tím, že si objednáte explicitně

I když to můžete udělat přes straight_join, můžete také explicitně získat zámky na řádcích, které chcete, duplikací select ...for update na ten, který chcete získat jako první.

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;

Protože se zamykání provádí v několika krocích, bylo by možné, aby se položky v 'barvách' tabulky změnily v době od nastavení dočasné tabulky do doby, kdy dokončíte získávání zámků na dvou tabulkách.

To může být pro vás v pořádku (tj. pokud chcete pouze upravit existující položky při zahájení transakce), ale mohlo by to způsobit drobné chyby, pokud to není to, co chcete.




  1. OBJEDNAT BY Alias ​​nefunguje

  2. přiřadit všechny výsledky while do proměnné

  3. Připravené prohlášení, které mi nedovoluje zavolat $mysqli->stmt_init()

  4. Ruby, Rails:drahokam mysql2, používá někdo tento drahokam? Je to stabilní?