Sebbene la risposta sopra sia vera in quanto SELECT ... FOR UPDATE impedirà a sessioni / transazioni simultanee di inserire lo stesso record, questa non è la verità completa. Attualmente sto combattendo con lo stesso problema e sono giunto alla conclusione che SELECT ... FOR UPDATE è quasi inutile in quella situazione per il seguente motivo:
Una transazione / sessione simultanea può anche eseguire un SELECT ... FOR UPDATE sullo stesso valore di record / indice e MySQL lo accetterà felicemente immediatamente (senza bloccare) e senza generare errori. Naturalmente, non appena l'altra sessione lo ha fatto, anche la tua sessione non può più inserire il record. Né la tua né l'altra sessione / transazione ottengono alcuna informazione sulla situazione e pensano di poter inserire in sicurezza il record fino a quando non provano effettivamente a farlo. Il tentativo di inserimento porta quindi a un deadlock oa un errore di chiave duplicata, a seconda delle circostanze.
In altre parole, SELECT ... FOR UPDATE impedisce ad altre sessioni di inserire i rispettivi record, MA anche se fai un SELECT ... FOR UPDATE e il rispettivo record non viene trovato, è probabile che tu non possa effettivamente inserisci quel record. IMHO, che rende inutile il metodo "prima query, poi inserisci".
La causa del problema è che MySQL non offre alcun metodo per realmente bloccare i record inesistenti. Due sessioni/transazioni simultanee possono bloccare contemporaneamente record inesistenti "PER AGGIORNAMENTO", cosa che in realtà non dovrebbe essere possibile e che rende lo sviluppo notevolmente più difficile.
L'unico modo per aggirare il problema sembra essere l'utilizzo di tabelle semaforiche o il blocco dell'intera tabella durante l'inserimento. Fare riferimento alla documentazione di MySQL per ulteriori riferimenti sul blocco di intere tabelle o sull'utilizzo di tabelle semaforiche.
Solo i miei 2 cent...