Мы пытаемся создать транзакционную таблицу, в которую регулярно добавляются только новые записи.
Эта простая таблица требует от нас постоянного добавления новых записей в нее с течением времени. Ожидается, что объем транзакций в этой таблице будет достаточно высоким, а также возможен периодический пакетный импорт транзакций (> 1000), выполнение которого может занять несколько секунд.
Из этих данных мы затем делаем набор операторов выбора, группирующих разные столбцы, чтобы вернуть требуемые значения.
В ходе нашего первоначального тестирования мы обнаружили узкое место, связанное с SQL Server, которое блокирует наши SELECT в середине транзакции INSERTS.
Ниже приведен простой пример, который можно использовать для иллюстрации проблемы.
- Простая таблица БД
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 блокирует инструкцию SELECT, даже если она не изменяет существующие данные?
Вопрос о бонусных баллах: Это «особенность» SQL Server, или мы могли бы найти ее и в других вариантах баз данных?
UPDATE
Теперь у меня было время найти локальную базу данных оракула и выполнить тот же простой тест. Этот тестовый проход, как я и ожидал.
Т.е. я могу выполнять запрос столько раз, сколько захочу, и он будет возвращать ноль, пока 1-я транзакция не завершится, а затем вернет 2.
Есть ли способ заставить SQL Server работать так? или нам нужно перейти на Oracle?