Gewoonlijk omvat de oplossing voor dergelijke gelijktijdigheidsproblemen transacties en optimistische vergrendeling :wanneer u de teller bijwerkt, voegt u een where
toe clausule om de oude waarde te controleren en het aantal bijgewerkte rijen te tellen.
v = select value from counter where id=x.
update counter set value = v+1 where value = v and id=x
Als de teller in de tussentijd is bijgewerkt, verandert de update geen enkele rij -- u weet dus dat u de transactie moet terugdraaien en de transactie nog een keer moet proberen.
Een probleem is dat dit kan leiden tot een hoge conflict , met slechts een paar transacties die slagen en veel die mislukken.
Het is dan misschien beter om vast te houden aan pessimistische vergrendeling , waar u de rij eerst vergrendelt en vervolgens bijwerkt. Maar alleen een benchmark zal het je vertellen.
BEWERKEN
Als u transactie gebruikt zonder optimistische vergrendeling, kan het volgende scenario gebeuren.
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
Beide transacties slagen, de waarde is 50, maar er is een inconsistentie.