Можно ли условно избежать полного нажатия на курок? - PullRequest
0 голосов
/ 28 марта 2020

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

Влияние на старую систему приемлемо.

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

Новая система работает приемлемо, отключив триггер в коде (VS Core с EntityFramework btw), выполнив обновление, а затем повторное включение кода в рамках транзакции. Мои коллеги не согласны с тем, отключен ли триггер для другого приложения во время обработки транзакции.

Я уже видел этот пост:

https://dba.stackexchange.com/questions/204339/sql-server-how-to-disable-trigger-for-an-update-only-for-your-current-session

И первый ответ - это решение, которое я использую. Мои коллеги говорят мне, что это не сработает. Я верю, что так и будет. Но ответы 2 - что бы ни противоречили первому ответу.

Мое тестирование также подтвердило первый ответ, но я должен быть уверен на 100% в этом.

TIA

1 Ответ

1 голос
/ 28 марта 2020

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

Вы должны найти способ разбивать обновления на меньшее количество операторов. Триггер срабатывает за оператор, а не за строку. EG EF Core выполняет пакетную обработку автоматически, или вы можете использовать TVP или SqlBulkCopy во временную таблицу и т. Д. c.

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

Да. Вы можете легко проверить, что отключение триггера требует блокировки Sch-M для таблицы на время транзакции, что несовместимо со всеми другими операциями доступа к таблице.

например,

use tempdb
drop table if exists t


create table t(id int primary key)

go
create trigger t_t on t after insert 
as
begin
  select 'trigger running' msg
end

go

begin transaction

go
disable trigger t_t on t 
go

select  object_name(resource_associated_entity_id) table_name, resource_lock_partition, request_mode, request_status 
from sys.dm_tran_locks
where request_session_id = @@spid 
and resource_type = 'OBJECT'
order by 1,2

rollback
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...