SQL Server - безопасно ли использовать @@ ROWCOUNT в многопоточных приложениях? - PullRequest
13 голосов
/ 22 января 2012

Я использую SQL Server 2008.

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

INSERT INTO A (ID) VALUES (1)
IF @@ROWCOUNT = 0
    PRINT 'NO ROWS AFFECTED'

Во время выполнения запроса тот же запрос может быть вызван снова приложением. Так что же произойдет, если текущее выполнение будет после INSERT, но до блока IF в этот момент .

Как вы думаете, @@ROWCOUNT может дать неверный результат по этой причине?

Или это всегда безопасно в его контексте?

Ответы [ 4 ]

21 голосов
/ 22 января 2012

Да - это безопасно. Он всегда ссылается на предыдущую операцию в текущем запросе

НО

если вы хотите узнать количество затронутых строк, сначала сохраните его в переменной , потому что после оператора IF счет @@ROWCOUNT сбрасывает

INSERT INTO A (ID) VALUES (1)
DECLARE @rc INT = @@ROWCOUNT
IF @rc = 0
    PRINT 'NO ROWS AFFECTED'
ELSE
  SELECT @rc AS RowsAffected
7 голосов
/ 22 января 2012

@@ ROWCOUNT является безопасным по объему и соединению.

Фактически, он считывает только последнее число строк оператора для этого соединения и области.Полные правила: здесь, в MSDN (курсоры, DML, EXECUTE и т. Д.)

Чтобы использовать его в последующих операторах, необходимо сохранить его в локальной переменной.

1 голос
/ 22 января 2012

Вы должны сохранить значение @@ROWCOUNT в локальной переменной, в противном случае после оператора IF его значение будет сброшено в ноль:

SET @rowCount = @@ROWCOUNT

IF @rowCount = 0 
   PRINT 'NO ROWS AFFECTED' 

Кроме этого, да, это безопасно.

0 голосов
/ 24 октября 2015

Краткий ответ: Да.

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

SQL Server готов правильно обрабатывать параллельный доступ независимо от того, является ли клиентское приложение многопоточным или нет. Если этот атрибут SQL Server не будет бесполезным в любом многопользовательском сценарии. С точки зрения сервера не имеет значения, является ли одновременный доступ вызванным одним многопоточным приложением или двумя приложениями, которые в настоящее время используют сервер одновременно несколькими пользователями.

Что касается этого пункта, то @@ rowcount - это только вершина айсберга, есть намного больше и более глубокая функциональность, с которой нужно правильно обращаться, когда на рисунке изображен параллельный доступ.

Наиболее практичной частью этой области является управление транзакциями и изоляция транзакций.

...