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

Come assicurarsi che non ci siano condizioni di gara nel database MySQL durante l'incremento di un campo?

Ecco 3 diversi approcci:

Aggiornamento atomico

update table set tries=tries+1 where condition=value;

e sarà fatto atomicamente.

Utilizza le transazioni

Se è necessario selezionare prima il valore e aggiornarlo nell'applicazione, è probabile che sia necessario utilizzare le transazioni. Ciò significa che dovrai utilizzare InnoDB, non le tabelle MyISAM. La tua query sarebbe qualcosa del tipo:

BEGIN; //or any method in the API you use that starts a transaction
select tries from table where condition=value for update;
.. do application logic to add to `tries`
update table set tries=newvalue where condition=value;
END;

se la transazione non riesce, potrebbe essere necessario riprovare manualmente.

Schema versione

Un approccio comune consiste nell'introdurre una colonna di versione nella tabella. Le tue domande avrebbero qualcosa del tipo:

select tries,version from table where condition=value;
.. do application logic, and remember the old version value.
update table set tries=newvalue,version=version + 1 where condition=value and version=oldversion;

Se l'aggiornamento non riesce/restituisce 0 righe interessate, nel frattempo qualcun altro ha aggiornato la tabella. Devi ricominciare da capo, ovvero selezionare i nuovi valori, eseguire la logica dell'applicazione e riprovare l'aggiornamento.