EXEC процедура не создает транзакцию. Очень простой тест покажет это:
create procedure usp_foo
as
begin
select @@trancount;
end
go
exec usp_foo;
@@ trancount внутри usp_foo равно 0, поэтому оператор EXEC не запускает неявную транзакцию. Если у вас запущена транзакция при вводе UpdateRemoteServer, это означает, что кто-то начал эту транзакцию, я не могу сказать, кто.
При этом использование удаленных серверов и DTC для обновления элементов будет работать довольно плохо. Другой сервер также SQL Server 2005 по крайней мере? Возможно, вы можете поставить в очередь запросы на обновление и использовать messaging между локальным и удаленным сервером и заставить удаленный сервер выполнять обновления на основе информации из сообщения. Он будет работать значительно лучше, потому что оба сервера будут иметь дело только с локальными транзакциями, и вы получите гораздо лучшую доступность из-за слабой связи в очереди сообщений.
Обновлено
Курсоры фактически не запускают транзакции. Типичная пакетная обработка на основе курсора обычно основана на курсорах и пакетных обновлениях в транзакциях определенного размера. Это довольно распространено для ночных заданий, так как обеспечивает лучшую производительность (пропускная способность журнала при увеличении размера транзакции), и задания могут быть прерваны и возобновлены без потери вечности. Упрощенная версия цикла пакетной обработки обычно выглядит следующим образом:
create procedure usp_UpdateRemoteServer
as
begin
declare @id int, @batch int;
set nocount on;
set @batch = 0;
declare crsFoo cursor
forward_only static read_only
for
select object_id
from sys.objects;
open crsFoo;
begin transaction
fetch next from crsFoo into @id ;
while @@fetch_status = 0
begin
-- process here
declare @transactionId int;
SELECT @transactionId = transaction_id
FROM sys.dm_tran_current_transaction;
print @transactionId;
set @batch = @batch + 1
if @batch > 10
begin
commit;
print @@trancount;
set @batch = 0;
begin transaction;
end
fetch next from crsFoo into @id ;
end
commit;
close crsFoo;
deallocate crsFoo;
end
go
exec usp_UpdateRemoteServer;
Я пропустил часть обработки ошибок (начало try / begin catch) и причудливые проверки @@ fetch_status (статическим курсорам они вообще не нужны). Этот демонстрационный код показывает, что во время выполнения запущено несколько разных транзакций (разные идентификаторы транзакций). Во многих случаях также развертывает точки сохранения транзакций для каждого обработанного элемента , чтобы они могли безопасно пропустить элемент, вызывающий исключение, используя шаблон, аналогичный шаблону в моей ссылке, но это не относится к распределенным транзакциям, поскольку точки сохранения и DTC не смешиваются.