Ich habe eine 24/7 Java-Anwendung (jdk1.5.0_19), die Multi-Thread ist, die OJDBC5 als die Kommunikation für Oracle 11g (11.2.0.3) verwendet. Nach dem Verifizieren des Inhalts des Threads ruft jeder Thread eine aufzulösende Anweisung auf, die vorbereitet wird, und führt dann aus, um Daten in die Tabelle einzufügen. Jetzt bei der Initialisierung gibt es eine Total JDBC 20 Connections. Seit einiger Zeit geht es wirklich gut, keine Probleme.Connection Pool hängt mit Java Multi-Thread-Programm
Aber vor kurzem gab es eine Instanz, wo es gerade während der Ausführung der aufrufbaren Anweisung in DB gehängt wurde.
2017-02-06 13:03:39,855 [Thread-1] INFO QCCOM_SocketWorker run - Worker thread launched.
2017-02-06 13:03:39,856 [Thread-1] INFO QCCOM_Socket recvMessage
2017-02-06 13:03:39,856 [Thread-1] INFO QCCOM_SocketWorker recvRequest
2017-02-06 13:03:39,856 [Thread-1] INFO ProcessHandler invoke
2017-02-06 13:03:39,856 [pool-1-thread-1] INFO HandlerValidator validateRequest
2017-02-06 13:03:39,857 [pool-1-thread-1] INFO ProcessHandler process - Processing request...
2017-02-06 13:03:39,857 [pool-2-thread-1] INFO JDBCHelper call - Atempting to retrieve connection.
2017-02-06 13:03:39,857 [pool-2-thread-1] INFO JDBCHelper call - Connection successfully retrieved
2017-02-06 13:03:39,857 [pool-1-thread-1] INFO JDBCHelper getConnection - Conn : [email protected]
2017-02-06 13:03:39,858 [pool-1-thread-1] INFO JDBCServiceImpl insertBP - Calling insert transaction stored procedure..
2017-02-06 13:03:43,856 [Thread-1] INFO ProcessHandler invoke - Worker Thread Timed out
2017-02-06 13:03:43,857 [Thread-1] DEBUG ProcessHandler invoke - [java.util.concurrent.FutureTask$Sync.innerGet(FutureTask.java:226), java.util.concurrent.FutureTask.get(FutureTask.java:100), ....ProcessHandler.invoke(ProcessHandler.java:114), com.qcom.qcm.qccom.QCCOM_SocketWorker.dispatch(QCCOM_SocketWorker.java:88), com.qcom.qcm.qccom.QCCOM_SocketWorker.run(QCCOM_SocketWorker.java:126)]
2017-02-06 13:03:43,857 [Thread-1] INFO QCCOM_SocketWorker run - Worker thread shutdown.
2017-02-06 13:03:55,661 [pool-1-thread-1] INFO JDBCServiceImpl insertBP - Callable Statement successfully closed!
2017-02-06 13:03:55,661 [pool-1-thread-1] INFO JDBCServiceImpl insertBP - Connection successfully closed!
2017-02-06 13:03:55,662 [pool-1-thread-1] INFO ProcessHandler process - Connection successfully closed!
Normalerweise passiert die Transaktion weniger als weniger als 200ms.
2017-02-06 13: 03: 39.858 [Pool-1-Faden-1] INFO JDBCServiceImpl insertBP - Berufung Einsatz Transaktion gespeicherte Prozedur ..
Aber im Beispiel oben haben wir einen hängen die Ausführung von Einfügen.
Siehe Code unten (JDBCServiceImpl insertBP).
public synchronized void insertBP(String A, BigDecimal Num, Date Date) throws SQLException{
CallableStatement cs = null;
logger.info("Calling insert transaction stored procedure..");
try{
cs = (CallableStatement) conn.prepareCall("{"+sql+"}");
cs.setString(1, tnxType);
cs.setBigDecimal(2, Num);
cs.setTimestamp(3, new Timestamp(Date.getTime()));
cs.execute();
} catch (SQLException sqlEx){
String strMessageContents = StringUtil.getFailedMessageContents(A, Num, Date);
String strErrorMessage = "Failed to insert ";
logger.fatal(strErrorMessage);
aUtil.emailFatal;
throw sqlEx;
} finally {
if (null!=cs){
cs.close();
logger.info("Callable Statement successfully closed!");
}
if (null!=conn){
conn.close();
logger.info("Connection successfully closed!");
}
}
}
Irgendwie hängt es auf cs.execute ... Dann Timeout Worker-Thread kommt und tötet die gesamte Transaktion, aber irgendwie ist es nicht die bereits eingeleiteten aufrufbaren Anweisung töten.
Ich habe auch einen Code für fail over, der die Hauptverbindung tötet, durch diese Methode wird die gesamte Verbindung getötet, was zu erfolgreichem Töten führt.
2017-02-06 13: 03: 55,661 [pool-1-thread-1] INFO JDBCServiceImpl insertBP - Callable Statement erfolgreich geschlossen!
-Code ist wie für Util
public void destroyHelper(){
AppJDBCHelper helper = null;
try {
helper = AppJDBCHelper.getInstance();
helper.destroy();
} catch (SQLException e) {
logger.fatal(e);
logger.debug(Arrays.toString(e.getStackTrace()));
}
}
Zusatzcode für AppJDBCHelper
public void destroy() throws SQLException{
DBConnectionPool pool = new DBConnectionPoolImpl();
pool.closeConnectionPool(ods);
helper = null;
logger.info("AppJDBCHelper destroy() success...");
}
Diese zwei Maschinen befinden sich im gleichen Schalter
if (Util.IsOffline){
logger.info("App is Offline attempting to reestablish connection.");
Util.destroyHelper();
logger.info("Previous Connection Pool Destroyed...");
logger.info("Reinitializing Connection Pool ...");
try {
AppJDBCHelper helper = AppJDBCHelper.getInstance();
if (null != helper){
logger.info("Connected to Schema: "+helper.getSchema());
logger.info("Connection Pool initialized ...");
Util.IsOffline = false;
logger.info("App has reestablished connection.");
}
if (null == helper){
logger.fatal("Failed to get database connection pool ...");
Util.destroyHelper();
}
} catch (SQLException e){
logger.fatal("Failed to connect to database ...");
logger.debug(Arrays.toString(e.getStackTrace()));
System.out.println(" \n >>> ERROR: Failed to connect to database ...");
Util.destroyHelper();
}
}
Zusätzlicher Code folgt, so ist es weniger Netzwerkreibung. und wie überprüft, gibt es keine Netzwerkprobleme während dieser Zeit. Auch DB Listener ist aktiv und war bereit Transaktionen zu akzeptieren.
Also meine Hauptfrage hier ist, was zum Teufel passiert und die aufrufbare Aussage hängt.
In der JVM wurden seit April 2009 Hunderte, wenn nicht Tausende von Fehlern behoben. Wenn Sie merkwürdiges Verhalten feststellen, möchten Sie es vielleicht mit einer neueren JVM oder sogar der neuesten später veröffentlichten Version von Java 5.0 testen Jahr. –
Yeah verstanden Ich habe dies auch vorgeschlagen, aber Client will immer noch nicht Java-Version zu aktualisieren. –
Verstanden. Können Sie sich mit einer Arbeit herumschlagen, wenn eine Lösung nicht offensichtlich erscheint? –