Как я могу использовать транзакции, которые охватывают процедуры, связанные между несколькими серверами?

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

У меня есть два сервера SQL Server 2005. Давайте для аргументации назовем их Server1 и Server2 [держите свои аплодисменты] , каждый из которых содержит фиктивная база данных. Фиктивная база данных на Server1 называется Source, а на Server2-Destination, просто чтобы все было просто. Каждая база данных содержит одну таблицу, называемую входом и выходом соответственно, поэтому структура квази объясняется следующим образом:

  • Server1.Источник.dbo.Ввод
  • Server2.Назначение.dbo.Вывод

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

теперь начинается хитрость:

  1. Я хочу создать хранимую процедуру на Server1.Источник, который вызывает хранимую процедуру WriteDataToOutput, определенную на Server2, которая кажется простым шагом.
  2. Я хочу, чтобы этот вызов был частью транзакции, так что если процедура, вызывающая его, терпит неудачу, вся транзакция откатывается.

и на этом заканчивается мое знание того, что делать. Может кто-нибудь мне точку в правильном направлении? Я попробовал это на двух разных базах данных на одном сервере, и это сработало просто отлично, заставив меня предположить, что он будет работать на разных серверах, вопрос в том, как я могу это сделать? С чего начать?

6 ответов


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

вот несколько указателей, которые зацепили меня в первый раз, когда я имел дело со связанными серверами:

  • если связанный сервер является экземпляром, убедитесь, что имя заключено в скобки. Например [SERVERNAME\INSTANCENAME].

  • используйте псевдоним для таблицы или представления со связанного сервера, или вы получите ошибку "многосоставной идентификатор не может быть связан". Есть предел 4 часть именования. Например, сервер.БАЗА ДАННЫХ.dbo.ТАБЛИЦА.Поле состоит из пяти частей и выдаст ошибку. Однако,SELECT linked.FieldName FROM SERVER.DATABASE.dbo.TABLE AS linked будет работать нормально


вы захотите связать серверы:

http://msdn.microsoft.com/en-us/library/aa213778.aspx


для шага 2 вам нужно запустить координатор распределенных транзакций, вам также нужно использовать SET XACT_ABORT ON, чтобы убедиться, что он будет откат вам также нужно включить RPC, который отключен по умолчанию в 2005 и выше

есть целая куча вещей, которые могут укусить вас в шею


MSDN говорит, что вы можете иметь транзакции на связанных серверах, если вы используете команду BEGIN DISTRIBUTED TRANSACTION.

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


используя связанные серверы, вы можете запускать хранимые процедуры на любом сервере в рамках одной транзакции с помощью DTC (Distributed Transactino Coordinator). Вы определенно захотите провести анализ производительности. Я обнаружил, что некоторые SPs с помощью ссылок могут резко замедлить производительность базы данных, особенно если вы пытаетесь присоединиться к наборам результатов с каждого из двух серверов.


настройте связанный сервер, затем вы сможете выполнять выбор / вставку / обновление на всех серверах. Что-то вроде:

INSERT INTO Server2.Destination.dbo.Output
SELECT * FROM Input  
WHERE <Criteria>

предполагается, что вы выполняете запрос от Server1.Источник, так что вам не нужно будет полностью квалифицироваться.