Wiederherstellung eines Ladevorgangs von SQL Server nach Oracle nach einem VPN-Abbruch
Ein abgebrochenes VPN lässt den Aufrufer im Unklaren, ob der Oracle-Commit angekommen ist. Eine dauerhafte Batch-ID macht Extraktion, Anwendung und Abgleich einzeln beantwortbar.
Eine datenbankübergreifende Übertragung stirbt, wenn das VPN abbricht, und „noch einmal ausführen“ ist kein Wiederherstellungsplan. Die Extraktion der Quelle kann abgeschlossen sein, das Ziel kann bereits committet haben, oder die Antwort ist einfach auf dem Rückweg verloren gegangen. Diese drei Zustände erfordern unterschiedliche Maßnahmen, und ein Client, der nur „Fehler“ kennt, kann sie nicht auseinanderhalten.
Die Lösung ist architektonisch: Geben Sie jedem Lauf eine dauerhafte Batch-Identität, und lassen Sie die Datenbanken Fragen beantworten, statt den Client raten zu lassen.
Was die Datenbank tatsächlich garantiert
SQL Server und Oracle bieten beide Atomarität innerhalb einer Transaktion. Keines bietet Ihnen Atomarität über beide hinweg. Eine verlorene Verbindung beschädigt die Datenbank nicht und erzwingt auch kein manuelles Rollback, weil der Server seine eigene Transaktion ohne Sie auflöst. Was zerbricht, ist das Wissen des Aufrufers über das Ergebnis.
Separat committet heißt separat committet. Ein VPN, das beide Verbindungen trägt, verschmilzt zwei Commits nicht zu einer Arbeitseinheit.
Der Commit, von dem Sie nie gehört haben
Ein Fehlermodus bestraft naive Wiederholungslogik: Der Server committet, und die Bestätigung erreicht den Aufrufer nie. Oracle dokumentiert dies als das Problem des unbekannten Ergebnisses und stellt dafür Transaction Guard in der Transaktionsdokumentation bereit. Ein Kommunikationsfehler ist kein Beweis dafür, dass ein übermittelter Commit fehlgeschlagen ist, und ihn als Beweis zu behandeln, ist der Weg, auf dem ein Batch zweimal gebucht wird. Der Unterschied zählt am meisten auf dem Wiederholungspfad, wo der Operator eine Fehlermeldung und kein anderes Signal zum Handeln hat.
Der Wiederherstellungsschritt muss das Ergebnis also beim Ziel lesen, statt es aus dem Fehlertext abzuleiten.
Geben Sie der Übertragung eine Batch-Identität
Jeder Lauf erhält eine unveränderliche Batch-ID, und das Ziel zeichnet auf, was es mit dieser ID getan hat. Der Lebenszyklus umfasst vier Schritte und sieht unabhängig vom Anbieter gleich aus:
- Extrahieren Sie einen identifizierten, unveränderlichen Quell-Batch mit aufgezeichnetem Schema und aufgezeichneter Grenze.
- Übertragen Sie ihn in den Stagingbereich des Ziels und erkennen Sie unvollständige oder widersprüchliche Inhalte, bevor er für bereit erklärt wird.
- Anwenden Sie ihn unter den eigenen Eindeutigkeits- oder Sperrregeln des Ziels und zeichnen Sie den Abschluss in derselben lokalen Transaktion auf.
- Abgleichen Sie das dauerhafte Ergebnis über das unterstützte Protokoll, bevor Sie bestätigen oder erneut versuchen.
Wiederholungen verwenden dieselbe ID. Eine neue ID pro Versuch untergräbt die Dublettenverhinderung, die Sie gerade gebaut haben, was offensichtlich klingt, bis ein Wiederholungs-Wrapper automatisch eine erzeugt.
Die ID gibt Ihnen außerdem etwas, wogegen Sie später abgleichen können, lange nachdem der Clientprozess verschwunden ist.
Beanspruchen Sie den Batch, dann wenden Sie ihn an
Der Anwendungsschritt muss die Batch-ID beanspruchen, die Geschäftsänderungen vornehmen und den Abschluss in einer lokalen Transaktion aufzeichnen. Prüfung und Einfügung als getrennte Anweisungen auszuführen, führt das Rennen wieder ein, das Sie entfernen wollten. Wenn zwei Worker konkurrieren, gewinnt genau eine Beanspruchung, und dem anderen wird es mitgeteilt.
Ein fehlender Abschlusssatz ist kein Beweis dafür, dass eine laufende Transaktion niemals committen wird. Die Beanspruchung muss konkurrierende Versuche serialisieren, oder das Protokoll muss das dauerhafte Ergebnis lesen, bevor es irgendetwas entscheidet.
Verwenden Sie den unterstützten Mechanismus der Datenbank für diese Serialisierung statt einer Prüfen-und-Wiederholen-Schleife im Anwendungscode.
Was das Design noch immer nicht versprechen kann
Staging macht die Arbeit wiederanlaufbar und verringert die Abhängigkeit von einer langlebigen Sitzung. Es erzeugt keinen einzelnen atomaren Commit über SQL Server, Oracle und welchen externen Seiteneffekt der Job auch immer ausführt. Wenn das Geschäft dies wirklich braucht, entwerfen und qualifizieren Sie eine unterstützte verteilte Transaktion oder einen Abgleichsprozess, einschließlich der Frage, wem Arbeit mit ungewissem Ausgang gehört. Alles Schwächere gehört in ein Abgleich-Runbook, nicht in den Übertragungscode.
Akzeptieren Sie Unterbrechungen an drei Stellen: während der Übertragung, während der Anwendung und nach dem Commit, aber vor der Bestätigung. Prüfen Sie dann das Geschäftsergebnis statt die Meldung des Clients, und lassen Sie das Batch-Journal sagen, ob die Arbeit unvollständig, committet oder noch ungelöst ist.