Я создаю хранимую процедуру, которая может увеличивать значение счетчика и возвращать значение, если этот вызов был ответственен за достижение MaxValue. Сложность заключается в том, что эта процедура будет вызываться быстро и параллельно из разных потоков и разных машин.
Пример сценария:
Два потока, выполняющиеся параллельно, вызывают одну и ту же хранимую процедуру для увеличения одного и того же счетчика. Предположим, что CounterId = 5 передается в качестве параметра для обоих. Прежде чем любой из них будет выполнен, запись счетчика в настоящее время имеет значения полей CounterValue = 9 и MaxValue = 10.
Я хочу, чтобы одна из процедур успешно увеличила CurrentValue до 10 и вернула результат, указывающий, что она несет ответственность за изменение, из-за которого CounterValue достиг MaxValue. Другая процедура не должна увеличивать значение (поскольку оно превысит 10) и должна возвращать результат, указывающий, что значение MaxReach для счетчика уже достигнуто.
Я думал о выполнении запроса до или после, но кажется, что это может оставить «дыру», в которой изменение может быть сделано отдельным потоком и привести к возврату ложного срабатывания/отрицательного результата.
Это только начало идеи для процедуры. Я чувствую, что ему нужна блокировка, транзакция или что-то в этом роде?
UPDATE SomeCounters
SET CounterValue = (CounterValue + @AddValue),
MaxReached = CASE WHEN MaxValue = (CurrentValue + 1) THEN 1 ELSE 0
WHERE CounterId = @CounterId
AND MaxReached = 0