Mysql
 sql >> Datenbank >  >> RDS >> Mysql

Wie kann sichergestellt werden, dass beim Erhöhen eines Felds keine Race-Bedingung in der MySQL-Datenbank vorliegt?

Hier sind 3 verschiedene Ansätze:

Atomisches Update

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

und es wird atomar erfolgen.

Verwenden Sie Transaktionen

Wenn Sie den Wert zuerst auswählen und in Ihrer Anwendung aktualisieren müssen, müssen Sie wahrscheinlich Transaktionen verwenden. Das bedeutet, dass Sie InnoDB verwenden müssen, nicht MyISAM-Tabellen. Ihre Abfrage würde etwa so aussehen:

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;

Wenn die Transaktion fehlschlägt, müssen Sie sie möglicherweise manuell wiederholen.

Versionsschema

Ein gängiger Ansatz besteht darin, eine Versionsspalte in Ihre Tabelle einzuführen. Ihre Abfragen würden etwa so aussehen:

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;

Wenn diese Aktualisierung fehlschlägt/0 betroffene Zeilen zurückgibt, hat jemand anderes die Tabelle in der Zwischenzeit aktualisiert. Sie müssen ganz von vorne beginnen – das heißt, die neuen Werte auswählen, die Anwendungslogik ausführen und die Aktualisierung erneut versuchen.