2017-01-25 11 views
1

У нас есть набор элементов в таблице, а дети-работники вызывают StoredProc(get_next_item), чтобы получить следующий предмет для обработки.SQL Server: Тупики во время маркера, выдающие хранимую процедуру в многопроцессном сценарии

Хранимая процедура придает token к элементу при каждом вызове и возвращает назад деталь в указанном ниже порядке

  • Первые товары с пометкой «P1»
  • И тогда остальные из них

Выборочные данные:

item priority token 
-------------------------- 
item1 P1  NULL 
item2 NULL NULL 
item3 P1  NULL 
item4 NULL NULL 
item5 P1  NULL 
item6 NULL NULL 
item7 NULL NULL 

хранимых процедур "Get_next_item":

Declare @token int, 
     @item varchar(50), 
     @prty varchar(50) 

EXEC get_token 'token_key',@token out 

BEGIN TRAN 
BEGIN TRY 
    SET ROWCOUNT 1 

    -- FIRST TRY P1 ITEMS (U1) 
    UPDATE Item_audit 
    SET token = @token 
    WHERE priority = 'P1' AND token IS NULL 

    SELECT @rows = @@ROWCOUNT 

    -- IF no more P1 then rest of the items (U2) 
    IF 0 = @rows 
    BEGIN 
     UPDATE Item_audit 
     SET token = @token 
     WHERE token IS NULL 

     SELECT @rows = @@ROWCOUNT 
    END 

    IF @rows <> 0 
    BEGIN 
     SELECT @item = item , @prty = priority 
     FROM Item_audit 
     WHERE token = @token 
    END 
END TRY 
BEGIN CATCH 
    IF @@TRANCOUNT > 0 
     ROLLBACK 

    SET @err_msg = 'Exception ' 

    GOTO ERROR 
END CATCH 

IF @@TRANCOUNT > 0 
    COMMIT 

Вопросы:

Тупики рассматриваются в отчетности обновлений (U1 & U2), когда несколько процессов UNIX вызвать StoredProc(get_next_item), почему?

ответ

0

Я бы заменил все эти обновления и несколько раз выбирал из таблицы с одним обновлением вместе с запросом предложения вывода.

Также переместите BEGIN TRAN и COMMIT TRAN внутри TRY BLOCK. Почему вы оставите транзакцию надолго, чтобы ее можно было откатить, если что-то пошло не так в блоке try? не имеет смысла.

Во всяком случае я бы переписать всю вещь что-то вроде ....

Declare @token int 
     ,@item varchar(50) 
     ,@prty varchar(50) 

EXEC get_token 'token_key',@token out 

BEGIN TRY 

BEGIN TRANSACTION; 

    Declare @L TABLE (item VARCHAR(50), [priority] VARCHAR(50), token INT); 

    WITH X AS (
       Select TOP 1 * 
       from Item_audit 
       WHERE ([priority] = 'P1' AND token IS NULL) 
        OR (token IS NULL) 
       ORDER BY [priority] desc 
    ) 
    UPDATE X 
     SET token = @token 
    OUTPUT inserted.token , inserted.[priority] , inserted.item 
    INTO @L (token , [priority], item) 


    Select @item = item 
     , @prty = [priority] 
     , @token = token 
    FROM @L 

COMMIT TRANSACTION;  
END TRY 

BEGIN CATCH 
    IF @@TRANCOUNT > 0 
     ROLLBACK TRANSACTION; 
    SET @err_msg = 'Exception ' 

END CATCH 
+0

Спасибо Али, интересно, что может быть причиной тупиков? – Shashi

+0

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

+0

** Обновление: ** Тупики, похоже, уходят, когда запросы были более конкретными, например 'U1: WHERE ISNULL (приоритет, '%^@ ^%') = 'P1' И токен IS NULL' и' U2: ГДЕ ISNULL (приоритет,%^@ ^%) <> 'P1' И токен IS NULL' – Shashi

 Смежные вопросы

  • Нет связанных вопросов^_^