Verteilte Transaktionen mit SQL Servern

Nicht immer liegen alle Daten, die man für ein Statement benötigt in der selben Datenbank oder auf dem selben Server. Man kennt zwar die Verwendung von Verbindungsservern und die erweiterte Syntax für die Objektqualifizierung (servername.datenbank.schema.objekt) und kommt damit in den meisten Fällen auch gut zurecht, aber das reicht nicht immer.

Gelegentlich gibt es aber die Anforderung Daten auf einem anderen Server zu aktualisieren, nachdem bestimmte Schritte auf dem lokalen Server erledigt sind. Dies kann man unter Umständen asynchron über eine Schnittstellentabelle erledigen, aber auch hiermit kommt man nicht immer zum Ziel. Möchte man Daten auf dem Zielsystem über einen Join mit Daten des aktuellen Systems aktualisieren, befindet man sich im Bereich der verteilten Transaktionen. Gelegentlich ist es zudem eine gute Idee, die Zugriffe auf den Verbindungsserver durch lokale Views zu kapseln. So erhält man identischen Code für Entwicklung und Produktion trotz Verwendung unterschiedlicher Verbindungsserver.

Pseudo-Code:
CREATE VIEW MeinViewSchema.V_LokaleView  
AS
SELECT
Feldliste FROM Verbindungsserver.Datenbank.Schema.Tabelle;
GO

UPDATE MeinViewSchema.V_LokaleView  
SET Feld = L.Feld
FROM MeinViewSchema.V_LokaleView R
INNER JOIN MeinTabellenSchema.LokaleTabelle L ON R.Benutzer = L.BenutzerErfassung;
Im obigen Beispiel wurden die Tabellen Aliase L für die lokale Tabelle, bzw. R für die gekapselte remote Tabelle verwendet.

Wählt man das obige Vorgehen, dann sind noch ein paar letzte Hürden zu nehmen, da Out-of-the-Box verteilte Transaktionen erst mal nicht zugelassen sind. Der erste Fehler den man erhält ist also:
Error Code: 0x8004d025, The partner transaction manager has disabled its support for remote/network transactions
Hierzu muss man wissen, dass unter den Betriebssystemen Windows Server 2003 SP1, Windows XP SP2, Windows Server 2008 und Windows Vista Sicherheitseinstellungen vorgenommen wurden, die den Zugriff erst mal unterbinden. Im folgenden Artikel sind hierzu einige Details aufgeführt: Troubleshooting Problems with MSDTC.

Als erstes gilt natürlich sicherzustellen, dass auf beiden Servern der "Distributed Transaction Coordinator" Service (MSDTC) läuft. Danach sind auf beiden Systemen die folgenden Schritte notwendig:

  • Gehe zu "Administrative Tools > Component Services"
  • Im linken Baum navigiere zu "Component Services > Computers > My Computer" (evtl. muss man mit Doppelklick den Knoten öffnen und hier ggf. etwas warten, bis ein Knoten erweitert wurde)
  • Rechts-Klick auf "My Computer", Auswählen "Properties"
  • Man wähle den "MSDTC" Reiter
  • Klicke den Button "Security Configuration"
  • Nun gilt es die folgenden Optionen auszuwählen "Network DTC Access", "Allow Remote Clients", "Allow Inbound/Outbound", "Enable Transaction Internet Protocol (TIP) Transactions" (Einige Optionen mögen je nach Anwendungsfall überflüssig sein, am besten man probiert dies aus. Im oben angegebenen Artikel findet man die Standard-Werte und Hintergründe zu den Optionen)
  • Der Service wird bei Beendigung des Dialogs automatisch neu gestartet
  • Ein Neustart des Servers sollte überflüssig sein, hat aber in hartnäckigen Fällen schon mal geholfen

Nachdem man diese Hürde genommen hat, wird man wahrscheinlich direkt auf den nächsten Fehler laufen:
Server: Msg 7391, Level 16, State 1, Line 1
The operation could not be performed because OLE DB provider "%ls" for linked server "%ls" was unable to begin a distributed transaction.


Hier hilft uns nun dieser Artikel mit dem Thema How to troubleshoot error 7391 that occurs when you use a linked server in SQL Server weiter. Wenn wir davon ausgehen, dass die Kommunikation funktioniert und auch die oben angegebenen Schritte erfolgt sind, läuft es in der Regel auf die Option
SET XACT_ABORT ON;
hinaus.

Schauen wir also mal in der Online-Doku nach. Dort steht:
Wenn SET XACT_ABORT auf ON festgelegt ist und eine Transact-SQL-Anweisung einen Laufzeitfehler auslöst, wird die gesamte Transaktion beendet, und es wird ein Rollback für sie ausgeführt.

Wenn SET XACT_ABORT auf OFF festgelegt ist, wird in einigen Fällen nur für die Transact-SQL-Anweisung, die den Fehler ausgelöst hat, ein Rollback ausgeführt, und die Transaktion wird fortgesetzt. Abhängig vom Schweregrad des Fehlers wird möglicherweise für die gesamte Transaktion ein Rollback ausgeführt, wenn SET XACT_ABORT auf OFF festgelegt ist. OFF ist die Standardeinstellung.
...Es ist erforderlich, dass XACT_ABORT für Anweisungen zur Datenänderung in einer impliziten oder expliziten Transaktion für die meisten OLE DB-Anbieter, einschließlich SQL Server, auf ON festgelegt ist.

Dort geht es dann weiter zu einem Artikel über verteilte Transaktionen.

Fazit: Verteilte Transaktionen erfordern etwas Konfigurationsaufwand, ermöglichen dafür aber die synchrone Verarbeitung von Daten über mehrere Instanzen hinweg. Aufwendige Umgehungen mit Schnittstellentabellen oder anderen asynchronen Mechanismen können dann entfallen.