Mysql
 sql >> Base de données >  >> RDS >> Mysql

Comment s'assurer qu'il n'y a pas de condition de concurrence dans la base de données MySQL lors de l'incrémentation d'un champ ?

Voici 3 approches différentes :

Mise à jour atomique

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

et cela se fera de manière atomique.

Utiliser des opérations

Si vous devez d'abord sélectionner la valeur et la mettre à jour dans votre application, vous devrez probablement utiliser des transactions. Cela signifie que vous devrez utiliser InnoDB, pas les tables MyISAM.Votre requête ressemblerait à :

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;

si la transaction échoue, vous devrez peut-être la réessayer manuellement.

Schéma de version

Une approche courante consiste à introduire une colonne de version dans votre tableau. Vos requêtes donneraient quelque chose comme :

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;

Si cette mise à jour échoue/renvoie 0 lignes affectées, quelqu'un d'autre a mis à jour la table entre-temps. Vous devez tout recommencer, c'est-à-dire sélectionner les nouvelles valeurs, effectuer la logique d'application et réessayer la mise à jour.