Rein theoretisch sieht es so aus, als würden Sie nicht die richtigen Zeilen sperren (andere Bedingung in der ersten Anweisung als in der Update-Anweisung; außerdem sperren Sie nur eine Zeile wegen LIMIT 1
, wobei Sie eventuell später weitere Zeilen aktualisieren).
Versuchen Sie Folgendes:
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;
[Bearbeiten]
Was den Grund für Ihren Deadlock betrifft, so ist dies die wahrscheinliche Antwort (aus dem Handbuch ):
Ohne einen Index ist das SELECT ... FOR UPDATE
-Anweisung sperrt wahrscheinlich die gesamte Tabelle, während sie bei einem Index nur einige Zeilen sperrt. Da Sie in der ersten Anweisung nicht die richtigen Zeilen gesperrt haben, wird während der zweiten Anweisung eine zusätzliche Sperre erworben.
Offensichtlich kann es nicht zu einem Deadlock kommen, wenn die gesamte Tabelle gesperrt ist (d. h. ohne Index). Beim zweiten Setup kann es durchaus zu einem Deadlock kommen.