Vanligtvis innebär lösningen på sådana samtidiga problem transaktioner och optimistisk låsning :när du uppdaterar räknaren, lägg till en where
för att kontrollera det gamla värdet och räkna antalet uppdaterade rader.
v = select value from counter where id=x.
update counter set value = v+1 where value = v and id=x
Om räknaren uppdaterades under tiden kommer uppdateringen inte att ändra någon rad – så du vet att du måste återställa och försöka en gång till med transaktionen.
Ett problem är att det kan leda till en hög konflikt , med endast ett fåtal transaktioner som lyckas och många som misslyckas.
Då kan det vara bättre att hålla sig till pessimistisk låsning , där du låser raden först och uppdaterar den sedan. Men bara ett riktmärke kommer att berätta.
REDIGERA
Om du använder transaktion utan optimistisk låsning kan följande scenario inträffa.
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
Båda transaktionerna lyckas, värdet är 50, men det finns en inkonsekvens.