Системные триггеры для репликации и опция NOCOUNT - PullRequest
1 голос
/ 06 декабря 2010

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

Можно ли ожидать, что сгенерированные системой триггеры будут использовать SET NOCOUNT ON чтобы их действия не влияли на значение функции @@ROWCOUNT?

Фон

Я использую NHibernate с базой данных Sql Server 2008.В базе данных включена репликация, которая создает сгенерированные системой триггеры для опубликованных таблиц, чтобы упростить передачу данных подписчикам.

Без репликации все работает нормально, но при проверке строк, затронутых репликацией, NHibernate не проходит проверку.Число строк, на которые ADO.Net заявляет, что оно затронуло, по-видимому, включает строки, на которые воздействует связанный триггер, в дополнение к строкам, на которые влияет сама команда.

В исходном вопросе я упомянул @@ROWCOUNT SqlСерверная функция, но на самом деле я имею в виду значение «затронутые строки», возвращаемое методом ADO.Net ExecuteNonQuery.Я предполагаю, что работал над предположением (возможно, неправильно), что последнее было передано первым.

В качестве временного решения мы изменили триггеры репликации, чтобы добавить SET NOCOUNT ON перед любыми обновлениями и отменить это.после завершения любых обновлений.Это решает нашу проблему в настоящее время, но не является жизнеспособным постоянным решением.Согласно полученному нами совету и здравому смыслу редактирование системных триггеров не рекомендуется.

Это, однако, наводит на мысль, что мы определили точную проблему.Строки, на которые влияют триггеры, включаются в итоговое число затронутых строк для текущей команды.NHibernate ожидает, что будет затронуто только известное количество строк, он не предусматривает каких-либо неизвестных (с точки зрения NHibernate) триггеров, добавляющих к этому счетчику.

В настоящее время мы находимся в процессе изучения вариантов, которыевключите расширение NHibernate, чтобы добавить возможность справиться или хотя бы подавить это.Наши ресурсы включают этот вопрос SO .

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

  1. Какова ситуация по умолчанию в отношении сгенерированных системой триггеров?
  2. Настраивается ли поведение?
  3. Зависит ли это от типа репликации - объединить,транзакционный?

1 Ответ

1 голос
/ 10 декабря 2010

Мне не удалось определить ответ на исходный вопрос - (должен / может / как) сгенерированные системой SQL Server триггеры репликации автоматически включают параметр SET NOCOUNT ON.

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

Опции, оставленные мне открытыми: ...

  1. Изменить / расширить NHibernate, чтобы не выбрасывать TooManyRowsAffectedException при обнаружении несоответствия числа строк.
  2. Удалите NHibernate и замените хранимыми процедурами и ручным отображением бизнес-объектов.

Мы выбрали вариант 1.

Мое решение состояло в том, чтобы изменить NHibernate (2.1) Ядро следующим образом ...

  1. Сначала я добавил новую опцию конфигурации для управления моим новым поведением.
  2. Затем я изменил сигнатуру методов VerifyOutcomeNonBatched и VerifyOutcomeBatched из класса NHibernate.AdoNet.Expectations, чтобы принять новое значение конфигурации в качестве параметра.Это включало изменение нескольких мест, где эти методы вызываются.
  3. Наконец, я изменил эти два метода, чтобы каждый из них выбрасывал / подавлял TooManyRowsAffectedException в соответствии с параметром конфигурации.

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

...