У меня есть таблица, которую я использую в качестве рабочей очереди. По существу, он состоит из первичного ключа, части данных и флага состояния (обрабатывается/не обрабатывается). У меня есть несколько процессов, пытающихся захватить следующую необработанную строку, поэтому я должен убедиться, что они соблюдают правильную семантику блокировки и обновления, чтобы избежать гадости. С этой целью я определил хранимую процедуру они могут позвонить:SQL Server SELECT/UPDATE Сохраненная процедура Weirdness
CREATE PROCEDURE get_from_q
AS
DECLARE @queueid INT;
BEGIN TRANSACTION TRAN1;
SELECT TOP 1
@queueid = id
FROM
MSG_Q WITH (updlock, readpast)
WHERE
MSG_Q.status=0;
SELECT TOP 1 *
FROM
MSG_Q
WHERE
[email protected];
UPDATE MSG_Q
SET status=1
WHERE [email protected];
COMMIT TRANSACTION TRAN1;
Обратите внимание на использование «С (UPDLOCK, READPAST)», чтобы убедиться, что я заблокировать целевую строку и игнорировать строки, которые так же запертые уже.
Теперь эта процедура работает, как указано выше, и это здорово. Однако, хотя я собирал это вместе, я обнаружил, что если второй SELECT и UPDATE меняются по порядку (т. Е. Сначала UPDATE, затем SELECT), я вообще не получил данных. И нет, неважно, был ли второй SELECT до или после окончательного COMMIT.
Таким образом, мой вопрос заключается в том, почему порядок второго SELECT и UPDATE имеет значение. Я подозреваю, что есть что-то тонкое, что я не понимаю, и я волнуюсь, что это укусит меня позже.
Любые подсказки?
Хм, ссылка кажется сломана, но это работает: http://msdn.microsoft.com/en-us/library/ms345108.aspx Кроме того, я застрял только с подключением ODBC к SQL-серверу db, поэтому я не уверен, что Service Broker будет работать на меня. Выглядит * отлично * хотя .... – 2009-02-18 19:44:18