Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

Como garantir que não haja condição de corrida no banco de dados MySQL ao incrementar um campo?


Aqui estão 3 abordagens diferentes:

Atualização atômica

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

e isso será feito atomicamente.

Usar transações


Se você precisar primeiro selecionar o valor e atualizá-lo em seu aplicativo, provavelmente precisará usar transações. Isso significa que você terá que usar InnoDB, não tabelas MyISAM. Sua consulta seria algo como:
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 a transação falhar, talvez seja necessário tentar novamente manualmente.

Esquema de versão


Uma abordagem comum é introduzir uma coluna de versão em sua tabela. Suas consultas fariam algo como:
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 essa atualização falhar/retornar 0 linhas afetadas, outra pessoa atualizou a tabela nesse meio tempo. Você tem que começar tudo de novo - ou seja, selecionar os novos valores, fazer a lógica da aplicação e tentar a atualização novamente.