Rent teoretisk ser det ud til, at du ikke låser de rigtige rækker (anden tilstand i den første sætning end i opdateringssætningen; desuden låser du kun én række på grund af LIMIT 1
, hvorimod du muligvis opdaterer flere rækker senere).
Prøv dette:
START TRANSACTION;
SELECT v_id FROM v_ext WHERE username IS NULL AND v_id=yyy FOR UPDATE;
UPDATE v_ext SET username=xxx WHERE v_id=yyy;
COMMIT;
[rediger]
Hvad angår årsagen til dit dødvande, er dette det sandsynlige svar (fra manualen ):
Uden et indeks er SELECT ... FOR UPDATE
sætning låser sandsynligvis hele tabellen, hvorimod den med et indeks kun låser nogle rækker. Fordi du ikke låste de rigtige rækker i den første sætning, opnås en yderligere lås under den anden sætning.
En deadlock kan naturligvis ikke ske, hvis hele bordet er låst (dvs. uden et indeks). En deadlock kan helt sikkert forekomme i den anden opsætning.