2008-09-11 6 views
12

Ich verstehe, auf eine unscharfe Weise, wie reguläre ACID-Transaktionen arbeiten. Sie führen einige Arbeiten an einer Datenbank so durch, dass die Arbeit erst bestätigt wird, wenn eine Art Commit-Flag gesetzt ist. Der Commit-Teil basiert auf einer zugrundeliegenden Annahme (wie ein einzelner Plattenblock-Schreibvorgang atomar ist). Im Falle eines katastrophalen Fehlers können Sie die nicht festgeschriebenen Daten in der Wiederherstellungsphase einfach löschen.Wie funktionieren verteilte Transaktionen (z. B. MSDTC)?

Wie funktionieren verteilte Transaktionen? In einigen der MS-Dokumentation habe ich gelesen, dass Sie unter anderem eine Transaktion über Datenbanken und Dateisysteme durchführen können.

Diese Technologie könnte (und ist wahrscheinlich) für Installationsprogramme verwendet werden, bei denen das Programm vollständig installiert oder vollständig fehlen soll. Sie starten einfach zu Beginn des Installationsprogramms eine Transaktion. Als Nächstes können Sie eine Verbindung zur Registrierung und zum Dateisystem herstellen und die Änderungen vornehmen, die die Installation definieren. Wenn der Job fertig ist, einfach Commit oder Rollback, wenn die Installation aus irgendeinem Grund fehlschlägt. Die Registrierung und das Dateisystem werden automatisch von diesem magischen verteilten Transaktionskoordinator für Sie bereinigt.

Wie ist es möglich, dass auf diese Weise zwei unterschiedliche Systeme abgewickelt werden können? Es scheint mir, dass es immer möglich ist, das System in einem inkonsistenten Zustand zu belassen, in dem das Dateisystem seine Änderungen festgeschrieben hat und die Registrierung dies nicht getan hat. Ich denke, in MSDTC ist es sogar möglich, eine Transaktion über das Netzwerk durchzuführen.

Ich habe gelesen http://blogs.msdn.com/florinlazar/archive/2004/03/04/84199.aspx, aber es fühlt sich an wie nur der Anfang der Erklärung, und dieser Schritt 4 sollte erheblich erweitert werden.

Edit: Von dem, was ich auf http://en.wikipedia.org/wiki/Distributed_transaction sammeln, kann es durch eine Zwei-Phasen-Commit (http://en.wikipedia.org/wiki/Two-phase_commit) erreicht werden. Nachdem ich das gelesen habe, verstehe ich die Methode immer noch nicht 100%, es scheint so, als gäbe es viel Platz für Fehler zwischen den Schritten.

+0

Da * ist * eine Menge Platz für Fehler. Insbesondere beruht es auf "COMMIT PREPARED", das immer funktioniert. Die Realität ist anders. –

Antwort

3

über „Schritt 4“:

Der Transaktionsmanager koordiniert mit den Ressourcenmanagern um sicherzustellen, dass alle angeforderten Arbeit oder keine der Arbeit zu tun, erfolgreich sein, wenn getan, so die ACID Aufrechterhaltung Eigenschaften.

Dies erfordert natürlich, dass alle Teilnehmer die richtigen Schnittstellen und (fehlerfreie) Implementierungen bereitstellen. Die Schnittstelle sieht aus wie vage dies:

public interface ITransactionParticipant { 
    bool WouldCommitWork(); 
    void Commit(); 
    void Rollback(); 
} 

Der Transaktionsmanager bei Festschreibungszeit fragt alle Teilnehmer, ob sie bereit sind, um die Transaktion zu begehen. Die Teilnehmer können dies nur dann geltend machen, wenn sie diese Transaktion unter allen zulässigen Fehlerbedingungen (Validierung, Systemfehler, etc.) durchführen können. Nachdem alle Teilnehmer die Transaktion bestätigt haben, sendet der Manager die Nachricht Commit() an alle Teilnehmer. Wenn ein Teilnehmer stattdessen einen Fehler oder Zeitüberschreitungen auslöst, wird die gesamte Transaktion abgebrochen und einzelne Mitglieder werden zurückgesetzt.

Dieses Protokoll erfordert, dass Teilnehmer ihren gesamten Transaktionsinhalt aufgezeichnet haben, bevor sie ihre Fähigkeit zum Commit bestätigen. Natürlich muss dies in einer speziellen lokalen Transaktionsprotokollstruktur sein, um aus verschiedenen Arten von Fehlern wiederherstellen zu können.

+3

Was passiert, wenn Sie Teilnehmer A und B haben, A wird festgeschrieben und gibt Erfolg zurück, dann wird das B festgeschrieben und gibt Fehler zurück, aber bevor A zurückgesetzt werden kann, fällt das Netzwerk ab? Ein anderer Fall wäre, dass der Netzwerkfehler B daran hindern könnte, begangen zu werden. – BCS

+0

B kann nicht auf Commit() fehlschlagen, nachdem true für "WouldCommitWork()" und "A" nicht übergeben wurde, bevor alle Teilnehmer "true" für "WouldCommitWork()" zurückgegeben haben. Alle Schritte des Protokolls haben Zeitüberschreitungen, die beim Treffer automatisches Rollback auslösen. Wenn ein Teil des Clusters fehlschlägt, muss er das Protokoll von einem nicht fehlerhaften Mitglied wiedergeben, um erneut beitreten zu können. Ausfallsichere Cluster gegen byzantinische Fehler sind ein heißes Forschungsthema und erfordern mehr als zwei Teilnehmer. –

+0

Der einzige Weg, wie B Fehler verhindern kann, ist das Sperren von Änderungen, die einen Fehler verursachen könnten, aber OK, also kratzen Sie die erste Option. OTOH-Hardware-Fehler bleibt weiterhin bestehen. - Ich interessiere mich für Fälle, in denen eine Verbindung fehlschlagen kann, während beide Systeme weiterhin andere Clients bedienen. In diesem Fall muss das System kohärent sein, selbst wenn eine unterbrochene Verbindung unterbrochen ist. Ich sehe nicht, wie sie sich jemals darauf einigen können, ob eine Transaktion durchgeführt werden soll, und stellen sicher, dass jeder zur gleichen Schlussfolgerung kommt. – BCS