SQL-запрос эксклюзивно для чтения / записи в таблицу - PullRequest
2 голосов
/ 06 декабря 2010

SQL Server 2008: У меня есть ситуация, когда я хочу читать из таблицы и записывать строку при определенных условиях.Проблема в том, что я не хочу, чтобы другой запрос приходил в одно и то же время и делал то же самое.Я попытаюсь объяснить здесь:

Имя таблицы: RequestQueue

Columns:

RequestID, StartDate, EndDate, RequestResult

Sample Data

1, 12/4/10 1:00pm, 12/4/10 1:02pm, Success
2, 12/4/10 1:04pm, 12/4/10 1:05pm, Success
3, 12/4/10 1:00pm, NULL, NULL

Когда страница загружается в мое приложение, я хочу, чтобы она посмотрела на эту таблицу иесли есть запрос, ожидающий ответа (ID # 3), он ничего не сделает.В противном случае, если нет ожидающих запросов, он создает новую строку с заполненными идентификатором и начальной датой.

Проблема заключается в том, что мы можем попасть в ситуацию, когда страница загружается дважды почти в одно и то же время.,Если они оба прочитают из таблицы перед созданием новой строки, то я мог бы получить две новые строки там.Я хочу иметь какой-то запрос, который читает из таблицы, и если нет ожидающих запросов, вставляет новую строку с заполненной StartDate. Я хочу, чтобы этот запрос выполнялся полностью, прежде чем другая страница сможет даже прочитать из этой таблицы, такЯ не получаю эффекта «двойной строки».

Мне может понадобиться «блокировка» или что-то в этом роде, я погуглил, но не нашел что-то для моей конкретной ситуации.Я уверен, что это может быть простая хранимая процедура, мне просто нужно нажать в правильном направлении.

Спасибо,

Роберт

1 Ответ

2 голосов
/ 06 декабря 2010

Предполагая, что вы просто хотите заблокировать весь параллельный доступ к таблице, которую вы можете просто сделать.

BEGIN TRAN 

DECLARE @StartDate datetime,
        @EndDate datetime

SELECT TOP 1
            @StartDate = StartDate,
            @EndDate = EndDate
        FROM     RequestQueue WITH(TABLOCK,XLOCK)
        ORDER BY RequestID DESC


IF @EndDate IS NULL
  SELECT @StartDate AS 'StartDate'
ELSE
  INSERT INTO RequestQueue (StartDate) 
  OUTPUT INSERTED.* /* Or use SCOPE_IDENTITY() instead*/
  VALUES (GETDATE())

COMMIT

В качестве альтернативы вы можете просто сериализовать доступ к коду SELECT/INSERT внутри конкретной процедуры, не используя эксклюзивную блокировку таблицы, используя sp_getapplock

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...