2015-10-16 1 views
1

Это скорее сообщение обмена знаниями.Проблемы параллелизма в счетчике счетчика SQL - проблема выбора/обновления

Недавно в одном из моих проектов я столкнулся с проблемой, которая довольно распространена, но на самом деле не задумывалась, пока я не столкнулся с ней. Существует множество решений, но почему-то я не нашел THE ONE, который я искал, и я собираюсь поделиться этим сообщением. Я уверен, что многие из вас уже знают о нижеследующем решении, но для тех, кто этого не делает, это определенно может быть спасателем жизни. :-)

Проблема:

В последнее время я работал на обслуживание окон. Эта служба должна была вставить некоторые записи в таблицу, которая долго существовала и использовалась несколькими другими старыми службами. Существует столбец (например, «ID»), который содержит целочисленное значение. Логика написана (наверное лет назад), чтобы получить целое число, чтобы вставить в этой таблице указано ниже:

Логика:

  1. Чтение значения из таблицы (скажем, таблица 1 - имя/значение пара),
  2. увеличивает его на 1
  3. обновить значение и
  4. Наконец получить новое значение [/ выделить].

Код

SELECT @value = [Value] from [dbo].[Table1] WHERE [Name] = @Name; 
UPDATE [dbo].[ Table1] SET [Value] = @value +1 WHERE [Name] = @Name; 
SELECT @value = @value+1; 

Применяемая технология имеет Основные вопросы параллелизм.

  1. же значение считывается несколько потоками
  2. Тупик проблема

Каков наилучший способ решения такой проблемы - Учитывая это упоминается во многих различных приложениях/услугах?

+3

Не могли бы вы отредактировать вопрос, чтобы он содержал только вопрос и создал отдельный ответ с вашим решением? См. [Можно ли ответить на мой собственный вопрос?] (Http://stackoverflow.com/help/self-answer) для получения дополнительной информации. – sstan

+0

И, возможно, добавить ссылки на документацию. Что такое 'OUTPUT insert 'и это для всех rdbms или для одного в частности? –

+0

Где приложение? –

ответ

1

Постановление

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

Моя цель - атаковать корень проблемы и избавиться от нее. Если я могу это сделать, то не должно быть реальных ударов. Результат proc будет таким же, поэтому для внешнего мира ничего не изменилось. :-)

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

Обновленный код

DECLARE @table table(
    Value int NOT NULL 
); 

-- Update the value and output the same into a local table variable 
UPDATE [dbo].[Table1] SET [Value] = [Value] + 1 OUTPUT inserted.[Value] INTO @table 
WHERE [Name] = @Name 

-- Now read the value from the local table variable 
SELECT Value FROM @table; 

Для получения дополнительной информации о выходе проверки п https://msdn.microsoft.com/en-us/library/ms177564(v=sql.90).aspx

Я провел несколько тестов с параллельно.foreach (20 000 раз). Моя тестовая таблица имела две записи -

  1. Name = Имя и Значение = 1 - После того, как 20 000 обновляет значение должно быть 20001
  2. Name = Во-вторых, значение = 100 - После того, как 20 000 обновляет значение должно быть 20100

Если вы проверите вложение, вы узнаете разницу в цифрах.

TestResults

вопросы Deadlock трудно воспроизвести, но проблема с несколькими потоками чтения и то же значение в ясно видно из результатов теста.

Любые мысли об этом приветствуются.

Как я уже говорил ранее, многие из вас уже знают это решение, но для тех, кто этого не делает, это может сэкономить некоторое время. :-)

+0

Вы видели [Обработка max (ID) в параллельной среде] (http://stackoverflow.com/q/7539997/ 1115360)? –

+0

Да, сейчас. Спасибо, что поделился. – Sourav

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