Обикновено решението на подобни проблеми с паралелността включва транзакции и оптимистично заключване :когато актуализирате брояча, добавете where
клауза, за да проверите старата стойност и да преброите броя на актуализираните редове.
v = select value from counter where id=x.
update counter set value = v+1 where value = v and id=x
Ако броячът е бил актуализиран междувременно, актуализацията няма да промени нито един ред – така че знаете, че трябва да върнете назад и да опитате още веднъж транзакцията.
Един от проблемите е, че това може да доведе до голямо спорване , само с няколко транзакции, които са успешни и много неуспешни.
Тогава може би е по-добре да се придържате към песимистичното заключване , където първо заключвате реда, след което го актуализирате. Но само бенчмарк ще ви каже.
РЕДАКТИРАНЕ
Ако използвате транзакция без оптимистично заключване, може да се случи следният сценарий.
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
И двете транзакции са успешни, стойността е 50, но има несъответствие.