Мы пытаемся иметь транзакционную таблицу, которая только принимает новые записи, вставленные на регулярной основе.
Эта простая таблица требует от нас постоянного добавления к ней новых записей с течением времени. Ожидается, что объем транзакций в этой таблице будет довольно высоким, а также может быть периодический импорт транзакций ( > 1000), который может занять несколько секунд.
Из этих данных мы затем выполняем набор операторов выбора, группирующих разные столбцы, чтобы вернуть требуемые значения.
Из нашего первоначального тестирования мы обнаружили, что узкое место должно быть связано с SQL Server, которое блокирует наш SELECT, когда находится в середине транзакции INSERTS.
Ниже приведен простой пример, который можно запустить, чтобы проиллюстрировать проблему.
- Простая таблица DB
create table LOCK_TEST (
LOCK_TEST_ID int identity ,
AMOUNT int);
- Запустить это в 1 окне запроса
begin tran
insert into LOCK_TEST (AMOUNT) values (1);
WAITFOR DELAY '00:00:15' ---- 15 Second Delay
insert into LOCK_TEST (AMOUNT) values (1);
commit
- В Query 2 выполните параллельное выполнение
select SUM(AMOUNT)
from LOCK_TEST;
Я ожидаю, что Query 2 вернется сразу, с 0 до завершения запроса 1, а затем покажет 2. Мы никогда не хотим видеть 1, возвращенный из второго запроса.
Ответ, который мы рассмотрели, связан с WITH (NOLOCK) в инструкции select. Но это нарушает транзакционные границы, и возвращаемая информация может носить финансовый характер, и мы не хотим видеть какие-либо детали в наших запросах.
Моя проблема, кажется, на стороне INSERT...
Почему INSERT блокирует оператор SELECT, даже если он не изменяет существующие данные?
Вопрос о бонусных точках: Является ли это "особенностью" SQL Server, или мы найдем это на других атрибутах базы данных?
UPDATE Теперь у меня было время найти локальную базу данных оракула и выполнить тот же простой тест. Этот тест проходит, как и следовало ожидать.
Т.е. я могу запускать запрос так часто, как хочу, и он будет возвращать значение null до момента совершения первой транзакции, а затем возвращает 2.
Есть ли способ заставить SQL Server работать так? или нам нужно перейти к Oracle?