sql >> Base de Datos >  >> RDS >> Mysql

¿Cómo asegurarse de que no haya una condición de carrera en la base de datos MySQL al incrementar un campo?

Aquí hay 3 enfoques diferentes:

Actualización atómica

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

y se hará de forma atómica.

Transacciones de uso

Si necesita seleccionar primero el valor y actualizarlo en su aplicación, es probable que necesite usar transacciones. Eso significa que tendrá que usar InnoDB, no las tablas MyISAM. Su consulta sería 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;

si la transacción falla, es posible que deba volver a intentarlo manualmente.

Esquema de versiones

Un enfoque común es introducir una columna de versión en su tabla. Sus consultas harían 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;

Si esa actualización falla/devuelve 0 filas afectadas, alguien más ha actualizado la tabla mientras tanto. Tienes que empezar de nuevo, es decir, seleccionar los nuevos valores, hacer la lógica de la aplicación e intentar la actualización de nuevo.