Требования
У меня есть следующая таблица (псевдо DDL):
CREATE TABLE MESSAGE (
MESSAGE_GUID GUID PRIMARY KEY,
INSERT_TIME DATETIME
)
CREATE INDEX MESSAGE_IE1 ON MESSAGE (INSERT_TIME);
Несколько клиентов одновременно вставляют строки в эту таблицу, возможно, много раз в секунду.Мне нужно спроектировать приложение «Монитор» , которое будет:
- Изначально извлекать все строки, находящиеся в настоящий момент в таблице.
- После этого периодически проверять,вставляются все новые строки, а затем извлекаются только эти строки * .
Возможно одновременное выполнение нескольких мониторов .Все Мониторы должны видеть все строки (то есть, когда строка вставлена, она должна быть "обнаружена" всеми текущими Мониторами ).
ЭтоПервоначально приложение будет разрабатываться для Oracle, но мы должны поддерживать его переносимость на все основные СУБД и избегать как можно большего числа специфических для базы данных данных.
Проблема
Наивное решениебыло бы просто найти максимальный INSERT_TIME в строках, выбранных на шаге 1, а затем ...
SELECT * FROM MESSAGE WHERE INSERT_TIME >= :max_insert_time_from_previous_select
... на шаге 2.
Однако, я боюсь, что это может привести кв гоночных условиях.Рассмотрим следующий сценарий:
- Транзакция A вставляет новую строку, но не все же фиксирует.
- Транзакция B вставляет новую строку и фиксирует.
- Монитор выбирает строки и видит, что максимальный INSERT_TIME - это тот, который вставлен B.
- Транзакция A фиксирует транзакцию.На данный момент INSERT_TIME А на самом деле на раньше , чем B (ВСТАВКА А фактически была выполнена до В, прежде чем мы даже знали, кто собирается совершить в первую очередь).
- Монитор выбирает строки, более новые, чем INSERT_TIME B (как следствие шага 3).Поскольку INSERT_TIME у A предшествует времени вставки B, строка A пропускается.
Итак, строка, вставленная транзакцией A, никогда не выбирается.
Любые идеи о том, как спроектировать клиентский SQLили даже изменить схему базы данных (если она слегка переносима), чтобы избежать подобных проблем параллелизма, сохраняя при этом приличную производительность?
Спасибо.