Hier sind meine schnellen Gedanken mit möglichen Umsetzungsschritten:
- Ihre Eltern Verarbeitungs-Thread wird (1.) neue Themen erstellen parallel DB Einsätze zu tun, (2.) erstellen
CountDownLatch
Objekt (Dadurch wird der übergeordnete Thread beibehalten, bis alle untergeordneten Threads, die DB-Einfügungen ausführen, beendet sind.) (3.) Erstellen Sie ein Db-Verbindungsobjekt mit Auto-Commit-Modus als FALSE.
- Angenommen, Sie 6 Threads laichen dann zu tun parallel DB fügt Sie
CountDownLatch
Objekt wie dieses CountDownLatch countDownLatch = new CountDownLatch(6)
schaffen und dann parallel Threads erzeugen und countDownLatch.await()
- Ihre parallele Threads tun Einfügen in DB starten, aber Schlüssel Sache ist, dass jeder von ihnen db Verbindungsobjekt im Auto-Commit-FALSE-Modus, der von übergeordneten Thread zur Verfügung gestellt wurde, so im Grunde kein Kind-Thread wird die Db-Commit.
- Sobald jeder untergeordnete Thread fertig ist, werden sie
countDownLatch.countDown();
tun, um den Latch-Zähler zu dekrementieren.
- Bitte beachten Sie, dass Sie die
countDownLatch
sowie db Verbindungsobjekt zu jedem Thread zur Verfügung stellen müssen, ich bin sicher, dass Sie wissen würden, wie.
Sobald Latch Zähler 0 erreicht, Ihre Mutter Thread-Ausführung wieder beginnen wird (bis Latch-Zähler nicht 0 ist, wird countDownLatch.await()
den Faden halten) und dann (1.) können Sie entscheiden, ob basierend zu begehen oder nicht auf Ergebnis von jedem Thread (2.) Schließen Sie das Verbindungsobjekt.Jetzt, Runnable
gibt nichts zurück, so besser nutzen Callable
, so dass jeder Thread über ihren Status informieren kann.
Wenn Sie Spring verwenden, kann es Ihre Arbeit mit seiner Transaktionsfunktion erleichtern, aber das wird eine andere Geschichte.
nun einige Punkte zu wissen, was Sie in Ihrer Frage erwähnt - Sie erwähnten „selbst wenn ein einzelner Thread zu begehen ausfällt, müssen alle Transaktions Rollback“, im Grunde, wenn alle Ihre db insert/Zugriff schlägt dann fehl Sie wollen nichts begehen, also wird Ihre Callable
den Status ihrer Ausführung zurückgeben, ich bin nicht sicher, was Sie sonst noch damit meinen könnten, aber ich denke, wenn Sie den Punkt über Callable
haben, dann sollten Sie in Ordnung sein. Außerdem erwähnten Sie ", aber das sieht wie schlechtes Design aus, da ich das Verbindungsobjekt unter Threads teile.", müssen Sie das Db-Verbindungsobjekt freigeben, weil, sobald eine Transaktion festgeschrieben ist, Sie kein Rollback durchführen können, also wollen Sie nicht Um das Verbindungsobjekt zu teilen, müssen Sie wahrscheinlich eine SQL-Anweisung haben, um die Arbeit, die durch den früheren Datenbankzugriff und ihre Commits erledigt wurde, rückgängig zu machen.
Verwenden Sie CountDownLatch im übergeordneten Thread https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/CountDownLatch.html. Verwenden Sie auch savePoint und Rollback, um den Rollback zu steuern und den Transaktionsfortschritt zu überwachen. Https://docs.oracle.com/javase/tutorial/jdbc/basics/transactions.html – Saurabh
savePoint und rollback funktionieren auf Verbindungsebene, und wenn ich sie verwende Mehrfachverbindung, dies wird nur das bestimmte txn zurückrollen, nicht alle txn, die gerade in anderen Threads ausgeführt werden. – RE350
Ich sehe, dann erfordert es die Verwendung einiger Transaktionsmanager. JBoss stellt einen zur Verfügung, wenn Sie diesen als App-Server verwenden, bindet dann aber Ihre Anwendung an JBoss. Ich erinnere mich nicht richtig daran, aber Spring hatte auch ein TM-Angebot. – Saurabh