Was ist die ‚beste‘ Art und Weise verteilte Transaktionen über mehrere Datenbanken zu tun mit Spring und Hibernate

StackOverflow https://stackoverflow.com/questions/128377

Frage

Ich habe eine Anwendung - mehr wie ein Dienstprogramm - die in regelmäßigen Abständen in einer Ecke und Updates zwei verschiedene Datenbanken sitzt.

Es ist eine wenig Standalone-Anwendung, die mit einem Federanwendungskontext gebaut wurde. Der Kontext hat zwei Hibernate Session Fabriken in konfiguriert, wiederum mit Commons DBCP Datenquellen konfiguriert im Frühjahr.

Zur Zeit gibt es keine Transaktionsmanagement, aber ich möchte einige hinzufügen. Das Update auf eine Datenbank hängt von einer erfolgreichen Update auf der anderen Seite.

Die App setzt sich nicht in einem Container Java EE - es durch eine statische Abschuss Klasse von einem Shell-Skript namens Bootstrap wird. Die Launcher Klasse instanziiert die Context-Anwendung und ruft dann eine Methode auf einem seiner Bohnen.

Was ist der ‚beste‘ Weg Transaktionalität um das Datenbank-Updates zu setzen?

Ich werde die Definition der ‚besten‘ Sie überlassen, aber ich denke, es sollte eine Funktion von ‚einfach einzurichten‘ sein ‚einfach zu konfigurieren‘, ‚billig‘ und ‚leicht zu verpacken und zu verteilen.‘ Natürlich FOSS wäre gut.

War es hilfreich?

Lösung

Der beste Weg, Transaktionen über mehr als eine Datenbank zu verteilen ist: Do not

.

Einige Leute zeigen Sie XA aber XA (oder zwei Phasen-Commit) ist eine Lüge (oder Marketingsprache).

Stellen Sie sich vor: Nach der ersten Phase dem XA-Manager gesagt hat, dass es die letzte commit senden kann, schlägt die Netzwerkverbindung zu einem der Datenbanken. Was jetzt? Auszeit? Das wäre die andere Datenbank beschädigt verlassen. Rollback? Zwei Probleme: Sie können nicht zurückrollen ein begehen und wie Sie wissen, was auf die zweite Datenbank ist passiert? Vielleicht hätte die Netzwerkverbindung, nachdem sie erfolgreich die Daten und nur die „Erfolgsmeldung“ begangen wurden, verloren?

Der beste Weg ist es, die Daten in einem einzigen Ort zu kopieren. Verwenden Sie ein Schema, das können Sie die Kopie abzubrechen und weiterhin jederzeit (zB ignorieren Daten, die Sie bereits haben oder die Auswahl der Reihenfolge von ID und fordern nur Datensätze> MAX (ID) Ihrer Kopie). Schützen Sie diese mit einer Transaktion. Dies ist kein Problem, da Sie nur Daten von der Quelle zu lesen, so dass, wenn die Transaktion aus irgendeinem Grunde ausfällt, können Sie die Quelldatenbank ignorieren. Daher ist dies eine einfache alte Hand Transaktion.

Nachdem Sie die Daten kopiert haben, zu verarbeiten lokal.

Andere Tipps

Setup ein Transaktionsmanager in Ihrem Kontext. Frühling docs haben Beispiele, und es ist sehr einfach. Dann, wenn Sie eine Transaktion ausführen:

try { 
    TransactionTemplate tt = new TransactionTemplate(txManager);

    tt.execute(new TransactionCallbackWithoutResult(){
    protected void doInTransactionWithoutResult(
            TransactionStatus status) {
        updateDb1();
        updateDb2();
    }
} catch (TransactionException ex) {
    // handle 
}

Weitere Beispiele und Informationen vielleicht bei so aussehen: XA-Transaktionen Frühling mit

Wenn Sie sagen, „zwei verschiedene Datenbanken“, haben Sie verschiedene Datenbankserver bedeuten, oder zwei verschiedene Schemata innerhalb der gleichen DB-Server?

Wenn die ehemaligen, dann, wenn Sie die volle Transaktionalität wollen, dann müssen Sie die XA-Transaktion API, die verpflichten voll zweiphasige zur Verfügung stellt. Aber noch wichtiger ist, müssen Sie auch einen Transaktionskoordinator / Monitor die Transaktion Ausbreitung zwischen den verschiedenen Datenbanksystemen verwaltet. Dies ist Teil der JavaEE spec und einem hübschen rarefied Teil davon dazu. Der TX-Koordinator selbst ist ein komplexes Stück Software. Ihre Anwendungssoftware (via Spring, wenn Sie möchten) im Gespräch mit dem Koordinator.

Wenn Sie jedoch nur zwei Datenbanken bedeuten im gleichen DB-Server, dann Transaktionen Vanille-JDBC sollten gut funktionieren, nur Ihre Operationen gegen beiden Datenbanken innerhalb einer einzigen Transaktion durchführen.

In diesem Fall würden Sie einen Transaktionsmonitor benötigen (Server unterstützt XA-Protokoll) und stellen Sie sicher, dass Ihre Datenbanken unterstützt auch XA. . Die meisten (? Alle) J2EE-Server kommt mit Transaktionsmonitor eingebaut Wenn Ihr Code nicht in J2EE-Server ausgeführt wird, dann gibt es Reihe von Standalone-Alternativen -. Atomicos, Bitronix, etc

Sie könnten Frühling ChainedTransactionManager versuchen - http://docs.spring.io/spring-data/commons/docs/1.6.2.RELEASE/api/org/springframework/data/transaction/ChainedTransactionManager.html dass db unterstützt verteilte Transaktion. Dies könnte eine bessere Alternative zu XA sein

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top