Das ist eine Menge Fragen :) Ich werde versuchen, die vorherigen Antworten zu vervollständigen.
Is there a better way to simulate the DB failure?
Testing alle Fälle ist kompliziert. Eine Möglichkeit, die Hauptfälle zu testen, wäre die Erstellung eines JCA-Connectors (ein DB-Treiber ist ist ein JCA-Connector). Sie können Verbindungen von dem Connector erhalten, der in der Transaktion eingetragen wird (ein dritter Teilnehmer). Die Verbindung kann dann bestimmte Fehler auslösen.
Es gibt drei Teile, die zusammenarbeiten: (1) die Anwendung, (2) die App. Transaktionsmanager des Servers und (3) der jca-Konnektor (sogenannter Ressourcenadapter).

Die Verbindungshaken sich in die Transaktion über ManagedConnection.getXAResource
. Mit einem benutzerdefinierten jca-Connector können Sie dann eine Exception für die Anwendung (Connection
im Bild) oder den Transaktionsmanager des Anwendungsservers (XAResource
, erhalten über die ManagedConnection
im Bild) auslösen. Sie können insbesondere während XAResource.prepare
und XAResource.commit
eine Ausnahme auslösen, die Fehlern während der 2-Phasen-Commit entspricht.
Beachten Sie, dass es schwierig ist, die Reihenfolge der Erfassung der Teilnehmer zu kontrollieren (siehe this question). So ist es einfach zu testen, dass einer der prepare
(deins) fehlschlägt, aber es ist schwer zu kontrollieren, in welcher Reihenfolge sie aufgerufen werden. Das Reproduzieren aller möglichen ungültigen Zustände des 2-Phasen-Commits ist kompliziert, insbesondere wenn die Optimierung ins Spiel gebracht wird.
(Ich schrieb einmal einen JCA-Anschluss (http://code.google.com/p/txfs) und es gibt andere, um, wenn Sie Beispielcode möchten.)
What happens to the connection object when DB connection goes bad?
Does it retain its value or does it become null?
Die ManagedConnection
an den Transaktionsmanager benachrichtigen können. Eine der Benachrichtigungen ist ConnectionEvent.CONNECTION_ERROR_OCCURRED
, die darauf hinweisen, dass bei der Verwendung dieser bestimmten Verbindung ein Fehler aufgetreten ist.
Wie in der anderen Antwort erwähnt, ist normalerweise pro Transaktion eine verwaltete Verbindung zugeordnet. Die verwaltete Verbindung abstrahiert die physische Verbindung, und Sie möchten nicht zu viele verwenden. Die Anwendung erhält nur "Handles" (Connection
im Bild). Die Handles, die innerhalb einer bestimmten Transaktion abgerufen werden, zeigen alle auf dieselbe verwaltete Verbindung. Dies ist eine Optimierung, die von den meisten App-Servern unterstützt wird.
Wenn die verwaltete Verbindung ungültig wird, werden die Handles, die sie verwenden, ebenfalls ungültig. Aber die Griffe können AFAIK nicht "aufgefrischt" werden. Die Transaktion muss zurückgesetzt werden, die verwaltete Verbindung wird zerstört. Wenn eine andere Transaktion gestartet wird, wird sie einer anderen gültigen verwalteten Verbindung aus dem Pool zugeordnet.
What actually happens when application tries to reconnect to DB?
What value does connection object get?
Does it use an existing value from the connection pool?
Der App-Server verwaltet einen Pool von verwalteten Verbindung. Wie bereits im vorherigen Absatz erwähnt, kann es passieren, dass es während der Verwendung schlecht wird. Aber man kann auch schlecht gehen ohne benutzt zu werden. Eine verwendete verwaltete Verbindung im Pool wird möglicherweise ungültig, da die zugrunde liegende physische Verbindung eine Zeitüberschreitung aufweist. App-Server verfügen normalerweise über eine Funktion, um zu testen, ob eine verwaltete Verbindung gültig ist, bevor sie sie verwendet.Ist dies nicht der Fall, versucht es eine andere verwaltete Verbindung aus dem Pool oder erstellt eine neue Verbindung.
Sind Sie auf eine bestimmte Datenbank ausgerichtet, oder muss dies eine verallgemeinerte Lösung für jede mit JDBC verbundene Datenbank sein? – kgrittn
Ich verwende momentan DB2 und DB2 z/OS. – Andy
Andy, welche Methode, um Datenbankfehler zu simulieren haben Sie gewählt? – dmiandre