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

MySQL:come ottenere il blocco delle transazioni a livello di riga anziché il blocco delle tabelle

Può essere utile osservare come questa query viene effettivamente eseguita da MySQL:

select * from tbl_codes where available = 1 order by rand() limit 1 for update

Questo leggerà e ordinerà tutte le righe che corrispondono a WHERE condizione, genera un numero casuale usando rand() in una colonna virtuale per ogni riga, ordina tutte le righe (in una tabella temporanea) in base a quella colonna virtuale, quindi restituisci le righe al client dal set ordinato fino al LIMIT viene raggiunto (in questo caso solo uno). Il FOR UPDATE influisce sul blocco eseguito dall'intera istruzione durante l'esecuzione e, in quanto tale, la clausola viene applicata quando le righe vengono lette all'interno di InnoDB , non man mano che vengono restituiti al cliente.

Mettendo da parte le ovvie implicazioni sulle prestazioni di cui sopra (è terribile), non otterrai mai un comportamento di blocco ragionevole da esso.

Risposta breve:

  1. Seleziona la riga che desideri, utilizzando RAND() o qualsiasi altra strategia di tuo gradimento, per trovare la PRIMARY KEY valore di quella riga. Es.:SELECT id FROM tbl_codes WHERE available = 1 ORDER BY rand() LIMIT 1
  2. Blocca la riga che desideri utilizzando la sua PRIMARY KEY solo. Es.:SELECT * FROM tbl_codes WHERE id = N

Spero che questo aiuti.