Ich habe einige grundlegende Verwirrung darüber, wie Transaktionen und msdtc zusammenarbeiten.
Ich habe eine Win Server-Winforms-App. Die App verwendet transactionscope, um mehrere SQL-Befehle zu kapseln, die auf dem SQL-Server ausgeführt werden.
Die App scheint gut zu funktionieren, wenn ich den msdtc-Netzwerkzugriff nur auf dem Server aktiviert habe. Dann eines Tages hörte es auf zu arbeiten, sagte Netzwerkzugriff wurde nicht aktiviert.
Nun scheint es, dass ich den msdtc-Netzwerkzugriff sowohl auf dem Client-Computer als auch auf dem Server aktivieren muss, damit transactionscope funktioniert.
Funktioniert der msdtc-Dienst des Clients oder Servers mit der Transaktion? Oder vielleicht beides?
Hat jemand eine Anleitung darüber, ob der msdtc-Netzwerkzugriff sowohl auf dem Client als auch auf dem Server oder nur auf dem Server benötigt wird?
Wenn Sie MSDTC verwenden, benötigen Sie sowohl den Client (Ihre Anwendung) als auch den Server (Datenbank), um sowohl MSDTC auszuführen als auch ordnungsgemäß konfiguriert zu sein.
Dies kann eine Quelle der Schmerzen sein, besonders im Umgang mit Firewalls. Wenn Sie Probleme haben, lesen Sie Probleme mit MSDTC beheben . Es spricht über BizTalk, aber es gilt für MSDTC im Allgemeinen. DTCPING ist auch dein Freund.
Wenn Sie jetzt SQL Server 2005 und höher verwenden, auf nur eine Datenbank zugreifen, eine Datenbankverbindung verwenden und keine Transaktionen zwischen App-Domänen weitergeben, sollten Sie die Verwendung von MSDTC nicht benötigen. Unter diesen Umständen wird der System.Transactions-Transaktionsmanager Ihre Transaktionen für Sie verwalten. Wenn eine der vorherigen Situationen auftritt, wird die Transaktion zu einer verteilten Transaktion befördert (und der Transaktionsmanager ist MSDTC). Weitere Informationen finden Sie unter Transaction Management Escalation .
Im Allgemeinen ist es am besten, die Verwendung von MSDTC zu vermeiden, wenn Sie sie nicht benötigen. Wenn Sie nur mit einer einzelnen SQL Server 2005+ -Datenbank arbeiten, sollten Sie versuchen, Ihren Code so zu entwerfen, dass er MSDTC nicht verwendet. Neben dem Konfigurationsaufwand führt DTC zu einer Leistungseinbuße, da alle Aufrufe von MSDTC außer Betrieb sind, kombiniert mit dem Overhead des Zweiphasen-Festschreibungsprotokolls (welches MSDTC verwendet).
Was in Ihrer spezifischen Situation passiert, ist schwer zu sagen. Wenn sich Ihr Code nicht geändert hat, haben sich vielleicht die Firewall-Regeln geändert? Ich habe auch gesehen, dass Windows Updates die DTC-Konfiguration (für die Sicherheit) ändern, was ein Problem verursacht hat.
Aktualisierung basierend auf Kommentar:
Wenn Sie keine verteilten Transaktionen verwenden, sollten Sie zur Überwachung der Transaktions-Promotion oder der Eskalation einige der Leistungsindikatoren für den verteilten Transaktions-Coordinator verwenden, um festgeschriebene Transaktionen zu verfolgen. Wenn Sie testen, können Sie MSDTC deaktivieren und sehen, ob Ihr Code fehlschlägt. Ein anderer Weg wäre, Transaktionen in SQL Server zu überwachen. Aus Codierungssicht könnten Sie versuchen, das DistributedTransactionStarted -Ereignis zu verarbeiten etwas Protokollierung (aber entfernen Sie diesen Code vor der Produktion).
Bei einem Codebeispiel mit einer einzelnen Verbindung gehen Sie zur Seite TransactionScope bei MSDN. Erstellen Sie im Grunde ein TransactionScope, erstellen Sie eine SqlConnection, arbeiten Sie mit der SqlConnection, schließen Sie die Verbindung, rufen Sie scope.Complete () auf.
Beachten Sie, dass bei Verwendung von Datenadaptermethoden die Verbindung automatisch so verwaltet wird, dass die Verbindung geschlossen oder an den Verbindungspool zurückgegeben wird. Wie auch immer, wenn eine andere Operation aufgerufen wird, wird die Transaktion zu einer DTC-Transaktion befördert. Weitere Informationen finden Sie unter System.Transactions und Verbindungspooling .
Um die Erklärung von @ Tuzo zu erweitern, hier ein Beispiel für einen Befehl, der immer eskalieren wird:
%Vor%In der Praxis werden die Verbindung und der Befehl in einer anderen Klasse usw. sein, aber Sie bekommen die Idee. Auch wenn die Verbindungszeichenfolge dieselbe Datenbank ist, eskaliert es mithilfe von DTC, da es zwei Verbindungen ist. Eine nicht eskalierende Transaktion wäre:
%Vor%Das ist sowieso der bessere Code, weil Sie die Verbindung öffnen, tun, was Sie brauchen, und so schnell wie möglich schließen. Dies bedeutet, dass Sie über Ihr Verbindungsmanagement nachdenken müssen. Abhängig von Ihrer App können Sie dies anders implementieren. Zum Beispiel:
%Vor%Es gibt verschiedene Möglichkeiten, dies zu implementieren. Enterprise-Bibliothek-Datenzugriffs-Anwendungsblock und verschiedene ORMs können Ihnen ebenfalls dabei helfen, Ihre Verbindungen und Transaktionen effizienter zu handhaben.
Update: Ich habe einen Artikel gefunden, der erklärt, warum Transaktionen von LTM zu MSDTC befördert werden, wenn nur GetData und Update auf demselben Datenadapter innerhalb eines TransactionScopes zusammen mit einer Problemumgehung verwendet werden.
Der endgültige Blogeintrag zu TableAdapters + Transactions Ссылка
Ich verstehe den Teil über das Öffnen mehrerer Verbindungen, die gleichzeitig eine zu verteilende Transaktion eskalieren. Ich habe jedoch ein Problem mit nur einer Verbindung und eine Abfrage mit einer Datenbank, die es eskaliert. In der gespeicherten Prozedur sind keine Transaktionen ebenfalls vorhanden. Wenn jemand eine Ahnung hat, würde ich gerne davon hören. In meinem Codebeispiel löst "adapter.Update (table)" eine verteilte Transaktion aus.
Ich habe den Kern des Codes aus meinem bestehenden Projekt herausgeholt und vereinfacht das meiste von dem, was vor sich ging, und ich habe immer noch die gleichen Probleme. Im Grunde wird ein Dataset mit einem Tabellenadapter erstellt und mit einer gespeicherten Prozedur zum Auswählen, Einfügen und Löschen eingerichtet. Ich wähle alle zugehörigen Datensätze mit einem bestimmten Benutzer aus. Dann, je nachdem ob für einen der Datensätze ein "myPPID" existiert, füge ich es hinzu oder lösche es. Ich rufe dann die Update-Methode auf und sehe, wie die Transaktion eskaliert, um sie zu verteilen, indem ich die Transaktionsstatistik in Komponentendiensten beobachte.
Ich verwende Windows XP Pro SP3 und .Net Framework 3.5 für das Client-Programm. Es verbindet sich mit einer SQL 2005-Datenbank über das LAN mit Windows Server 2003 R2 Enterprise Edition SP2.
%Vor%Die Verbindungszeichenfolge ist nichts besonderes:
%Vor%Auch die gespeicherten Prozeduren sind einfache Crud-Aufrufe.
Erstellen:
%Vor%Lesen:
%Vor%Löschen:
%Vor%Tags und Links .net winforms transactions msdtc