Por lo general, la solución a tales problemas de concurrencia involucra transacciones y bloqueo optimista. :cuando actualice el contador, agregue un where
cláusula para comprobar el valor antiguo y contar el número de filas actualizadas.
v = select value from counter where id=x.
update counter set value = v+1 where value = v and id=x
Si el contador se actualizó mientras tanto, la actualización no cambiará ninguna fila, por lo que sabe que debe retroceder e intentar una vez más la transacción.
Un problema es que podría conducir a una alta contención , con solo unas pocas transacciones que tienen éxito y muchas que fallan.
Entonces podría ser mejor ceñirse al bloqueo pesimista , donde primero bloquea la fila y luego la actualiza. Pero solo un punto de referencia te lo dirá.
EDITAR
Si usa la transacción sin bloqueo optimista, podría ocurrir el siguiente escenario.
Max authorized = 50. Current value = 49.
T1: start tx, read value --> 49
T2: start tx, read value --> 49
T1: update value --> 50, acquire a row lock
T1: commits --> release the lock
T2: update value --> 50, acquire a row lock
T2: commits --> release the lock
Ambas transacciones tienen éxito, el valor es 50, pero hay una inconsistencia.