So kann c3p0 Ihnen nicht sagen, ob eine Datenbank "down" ist. Metaphysisch, erkenntnistheoretisch hat es keinen Zugang zu diesen Informationen. Es beobachtet nur Schatten des DBMS an den Wänden des Netzwerks.
Es gibt ein paar Sache c3p0 kann, obwohl für Sie tun:
- Es kann Verbindungen testen, bevor sie Ihnen geben
- Es kann dich nicht verlassen
- hängen können Sie fragen, es im Voraus, ob Es gibt wahrscheinlich Verbindungen, die ohne Wartezeit verfügbar sind.
Es klingt wie Sie bereits c3p0 zu testen Anschlüsse für Sie an der Kasse, entweder über hibernate.c3p0.validate
oder c3p0.testConnectionOnCheckout
gebeten haben. Wenn dies nicht der Fall wäre, würde Ihre Anwendung bei getConnection() nicht hängen bleiben, wenn die Datenbank inaktiv ist. Sie sehen nur Fehler, wenn Sie versuchen, die Verbindung zu verwenden. (Möglicherweise testen Sie Verbindungen beim Einchecken und im Leerlauf. Weitere Informationen hierzu finden Sie weiter unten.)
Statt mit einem Hang aufzufallen, könnten Sie den Konfigurationsparameter c3p0.checkoutTimeout einstellen, so dass c3p0 keinen guten Wert hat Verbindung, um Sie relativ schnell zu übergeben, es befreit Sie mit einer Ausnahme.
Im Idealfall möchten Sie vielleicht nur im Voraus wissen, ob eine gute Verbindung verfügbar ist, bevor Sie versuchen, es auszuprobieren und sogar kurz hängen. Sie können c3p0 fragen, ob Verbindungen wahrscheinlich sofort verfügbar sind, und zwar über Methoden auf der PooledDataSource Schnittstelle von c3p0. Wenn Sie Zugang zu einem PooledDataSource pds
hatte, würde man nur so etwas wie
int idle = pds.getNumIdleConnectionsDefaultUser();
und konnte wissen, ob ein Anruf getConnection()
schnell zum Erfolg wahrscheinlich wäre, wenn es zumindest einige Verbindungen im Leerlauf sind. (Sie können keine Garantie geben, da c3p0 und Hibernate sehr asynchron sind. Zwischen Ihrem Scheck und Ihrem Checkout-Versuch können sich die Dinge also ändern.Und nein, kann man nicht versuchen, einen synchronized
Block oder etwas zu verwenden, um diese Dinge Atom zu machen, c3p0 Becken ihre tun Sperren intern, nicht an der äußeren DataSource
Ebene.)
Aber selbst wenn es Verbindungen im Leerlauf sind, Sie haben gewonnen Ich weiß nicht, ob sie gut sind, bis du sie testest, und wenn das DBMS nicht funktioniert, wirst du hängen bleiben, während c3p0 alle Verbindungen im Leerlauf versucht, sie ablehnt und dann vergeblich wartet, um Verbindungen zu erhalten. Was Sie möchten, ist, dass c3p0 die Connections vorab getestet hat, so dass, wenn keine gut sind, keine leer angezeigt werden.
Sie können das nicht perfekt erreichen, aber Sie können die Verbindungstests beim Checkout durch Verbindungstests bei der Prüfung in Verbindung mit häufigen Tests von Leerlaufverbindungen ersetzen. Einzelheiten hierzu finden Sie unter c3p0's docs. Wenn Sie dies tun, werden fehlerhafte Verbindungen schnell aus dem Pool entfernt und die Anzahl der Verbindungen im Leerlauf wird sich annähern. So haben Sie etwas, wenn auch unvollständig, Vertrauen, dass, wenn Sie im Leerlauf Verbindungen sehen, das DBMS ist und ein Anruf an getConnection()
wird schnell gelingen. Sichern Sie das mit einem checkoutTimeout
für den Zeitraum, wenn das DBMS gerade abgestürzt ist, aber c3p0 hat es noch nicht erkannt, und Sie werden ziemlich nah sein, wo Sie sein möchten.
Oh, das PooledDataSource von einem Hibernate Verbindungsanbieter zu erhalten, looking at the source code, sollte diesen Code so etwas wie ...
import com.mchange.v2.c3p0.PooledDataSource;
PooledDataSource pds = provider.unwrap(PooledDataSource.class);
int idle = pds.getNumIdleConnectionsDefaultUser();
Ich habe nicht versucht sein, und schreibe diese in einem schrecklichen Eile (sorry !), aber das sollte funktionieren, wenn es diese Mühe wert ist. Ich denke, dass die meisten Benutzer nur die Zeitkosten eines Datenbankausfalls begrenzen, indem sie c3p0.checkoutTimeout
verwenden, ohne sich die Mühe zu machen, die PooledDataSource
nach Leerlaufverbindungen zu fragen. Aber wenn Sie das brauchen, können Sie es bekommen.
Ich verstehe diesen Begriff "Kasse" nicht. Könnten Sie bitte erklären? – mpmp
Wenn Sie "getConnection()" auf einer c3p0 "PooledDataSource" (oder einem von einem gehosteten "Connector" aufrufen), wird es nicht aus der Datenbank abgerufen, sondern nur aus dem Pool "Verbindung" ausgecheckt. Wenn Sie festlegen möchten, wie lange dieser Checkout - der Aufruf von 'getConnection()' dauern kann, verwenden Sie 'c3p0.checkoutTimeout'. –