Задать вопрос

Как гарантировать монотонное увеличение значения поля при параллельных транзакциях с максимальным быстродействием?

Упрощённо имеются две таблицы:

1. CREATE TABLE dbo.Events(
EventNumber INT AUTOINCREMENT
)
2. CREATE TABLE dbo.ProcessedEvents (
LastEventNumber INT NOT NULL
)

В таблицу Events параллельно вставляют данные разные producer'ы.
Параллельно работает consumer' который делает след. запрос и после обработки сохраняет LastEventNumber:
SELECT TOP 1 
    e.EventNumber as LastEventNumber 
FROM 
    dbo.Events e JOIN dbo.ProcessedEvents pe
         ON e.EventNumber > LastEventNumber  
ORDER BY 
    e.EventNumber ASC


Как избежать проблемы в этом сценарии:

A> BEGIN;
B> BEGIN;
A> INSERT INTO dbo.Events() ... -- EventNumber = 1
B> INSERT INTO dbo.Events()... -- EventNumber = 2
B> COMMIT;

Если в этот момент времени произойдёт SELECT (READ COMMITED), то LastEventNumber станет 2

A> COMMIT;

В результате EventNumber = 1 будет пропущен consumer'ом.
Как избежать этой ситуации без lock'ов и сериализации транзакций, при этом гарантируя очерёдность событий?
  • Вопрос задан
  • 384 просмотра
Подписаться 4 Простой 1 комментарий
Ответ пользователя Vitsliputsli К ответам на вопрос (3)
@Vitsliputsli
А почему транзакция? Или они неявные? Инсерт должен быть атомарным или все таки итерирование сиквенса и следующая вставка не атомарны?
В любом случае, вы решаете не ту задачу. Если идет гонка, значит события одномоменты и нам должно быть без разницы в каком порядке они отработают. Но, раз это важно, значит эти события зависимы, если так, то манипуляции с вставкой не помогут, сегодня вы победите порядок коммитов, а завтра будет гонка при получении сиквенса и тут уже ничего не сделаешь. Зависимые события должны обрабатываться последовательно в одном потоке, т.е. в вашем случае их должен обрабатывать один продюсер, иначе никак, если даже сегодня заработает, то завтра малейшая флуктуация поменяет порядок. Как альтернатива вы можете построить сложную логику проверки зависимостей, но контролировать такой код будет гораздо сложнее.
Ответ написан
Комментировать