2011-06-02 1 views
1

Mon application semble être suspendue du jour au lendemain en raison de la perte de connexion (je pense que c'est le problème). Comment puis-je structurer mon application pour qu'elle tente d'établir une nouvelle connexion?Gestion de l'application Java pour les connexions supprimées

Depuis l'incident j'ai mis à jour la méthode getConnection() que mon application utilise comme ceci:

private Connection getConnection() { 
    boolean failed = false; 
    try{ 
     failed = !connection.isValid(1000); 
    }catch(SQLException ex){ 
     System.out.println("WARNING: Connection not valid!"); 
    } 
    try{ 
     failed = connection.isClosed(); 
    }catch(SQLException ex){ 
     System.out.println("WARNING: Connection is closed!"); 
    } 
    if(failed){ 
     System.out.println("Renewing connection"); 
     this.initializeConnection(); 
    } 
    return connection; 
} 

Ceci est la sortie:

** BEGIN NESTED EXCEPTION ** 

com.mysql.jdbc.exceptions.jdbc4.CommunicationsException 
MESSAGE: The last packet successfully received from the server was54521 seconds 
ago.The last packet sent successfully to the server was 54521 seconds ago, which 
    is longer than the server configured value of 'wait_timeout'. You should consi 
der either expiring and/or testing connection validity before use in your applic 
ation, increasing the server configured values for client timeouts, or using the 
Connector/J connection property 'autoReconnect=true' to avoid this problem. 

STACKTRACE: 

com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: The last packet success 
fully received from the server was54521 seconds ago.The last packet sent success 
fully to the server was 54521 seconds ago, which is longer than the server conf 
igured value of 'wait_timeout'. You should consider either expiring and/or testi 
ng connection validity before use in your application, increasing the server con 
figured values for client timeouts, or using the Connector/J connection property 
'autoReconnect=true' to avoid this problem. 
     at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) 

     at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source) 

     at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Sou 
rce) 
     at java.lang.reflect.Constructor.newInstance(Unknown Source) 
     at com.mysql.jdbc.Util.handleNewInstance(Util.java:406) 
     at com.mysql.jdbc.SQLError.createCommunicationsException(SQLError.java:1 
074) 
     at com.mysql.jdbc.MysqlIO.send(MysqlIO.java:3246) 
     at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1917) 
     at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2060) 
     at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2536) 
     at com.mysql.jdbc.ConnectionImpl.setCatalog(ConnectionImpl.java:4962) 
     at com.mysql.jdbc.DatabaseMetaData.getCallStmtParameterTypes(DatabaseMet 
aData.java:1506) 
     at com.mysql.jdbc.DatabaseMetaData.getProcedureOrFunctionColumns(Databas 
eMetaData.java:4120) 
     at com.mysql.jdbc.DatabaseMetaData.getProcedureColumns(DatabaseMetaData. 
java:4057) 
     at com.mysql.jdbc.CallableStatement.determineParameterTypes(CallableStat 
ement.java:809) 
     at com.mysql.jdbc.CallableStatement.<init>(CallableStatement.java:609) 
     at com.mysql.jdbc.JDBC4CallableStatement.<init>(JDBC4CallableStatement.j 
ava:46) 
     at sun.reflect.GeneratedConstructorAccessor6.newInstance(Unknown Source) 

     at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Sou 
rce) 
     at java.lang.reflect.Constructor.newInstance(Unknown Source) 
     at com.mysql.jdbc.Util.handleNewInstance(Util.java:406) 
     at com.mysql.jdbc.CallableStatement.getInstance(CallableStatement.java:5 
05) 
     at com.mysql.jdbc.ConnectionImpl.parseCallableStatement(ConnectionImpl.j 
ava:3881) 
     at com.mysql.jdbc.ConnectionImpl.prepareCall(ConnectionImpl.java:3965) 
     at com.mysql.jdbc.ConnectionImpl.prepareCall(ConnectionImpl.java:3939) 
     at com.protocase.hmiclient.db.HMIDatabaseAdapter.getAvailableBatchesForW 
orkstation(HMIDatabaseAdapter.java:471) 
     at com.protocase.hmiclient.views.WorkstationContainer.getBatches(Worksta 
tionContainer.java:74) 
     at com.protocase.hmiclient.views.BatchList.<init>(BatchList.java:55) 
     at com.protocase.hmiclient.views.WorkstationContainer.goToBatchList(Work 
stationContainer.java:56) 
     at com.protocase.hmiclient.views.forms.BatchListControlPanel.refreshButt 
onActionPerformed(BatchListControlPanel.java:118) 
     at com.protocase.hmiclient.views.forms.BatchListControlPanel.access$200(
BatchListControlPanel.java:16) 
     at com.protocase.hmiclient.views.forms.BatchListControlPanel$3.actionPer 
formed(BatchListControlPanel.java:64) 
     at javax.swing.AbstractButton.fireActionPerformed(Unknown Source) 
     at javax.swing.AbstractButton$Handler.actionPerformed(Unknown Source) 
     at javax.swing.DefaultButtonModel.fireActionPerformed(Unknown Source) 
     at javax.swing.DefaultButtonModel.setPressed(Unknown Source) 
     at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(Unknown Sour 
ce) 
     at java.awt.Component.processMouseEvent(Unknown Source) 
     at javax.swing.JComponent.processMouseEvent(Unknown Source) 
     at java.awt.Component.processEvent(Unknown Source) 
     at java.awt.Container.processEvent(Unknown Source) 
     at java.awt.Component.dispatchEventImpl(Unknown Source) 
     at java.awt.Container.dispatchEventImpl(Unknown Source) 
     at java.awt.Component.dispatchEvent(Unknown Source) 
     at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source) 
     at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source) 
     at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source) 
     at java.awt.Container.dispatchEventImpl(Unknown Source) 
     at java.awt.Window.dispatchEventImpl(Unknown Source) 
     at java.awt.Component.dispatchEvent(Unknown Source) 
     at java.awt.EventQueue.dispatchEventImpl(Unknown Source) 
     at java.awt.EventQueue.access$000(Unknown Source) 
     at java.awt.EventQueue$1.run(Unknown Source) 
     at java.awt.EventQueue$1.run(Unknown Source) 
     at java.security.AccessController.doPrivileged(Native Method) 
     at java.security.AccessControlContext$1.doIntersectionPrivilege(Unknown 
Source) 
     at java.security.AccessControlContext$1.doIntersectionPrivilege(Unknown 
Source) 
     at java.awt.EventQueue$2.run(Unknown Source) 
     at java.awt.EventQueue$2.run(Unknown Source) 
     at java.security.AccessController.doPrivileged(Native Method) 
     at java.security.AccessControlContext$1.doIntersectionPrivilege(Unknown 
Source) 
     at java.awt.EventQueue.dispatchEvent(Unknown Source) 
     at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source) 
     at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source) 
     at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source) 
     at java.awt.EventDispatchThread.pumpEvents(Unknown Source) 
     at java.awt.EventDispatchThread.pumpEvents(Unknown Source) 
     at java.awt.EventDispatchThread.run(Unknown Source) 
Caused by: java.net.SocketException: Software caused connection abort: socket wr 
ite error 
     at java.net.SocketOutputStream.socketWrite0(Native Method) 
     at java.net.SocketOutputStream.socketWrite(Unknown Source) 
     at java.net.SocketOutputStream.write(Unknown Source) 
     at java.io.BufferedOutputStream.flushBuffer(Unknown Source) 
     at java.io.BufferedOutputStream.flush(Unknown Source) 
     at com.mysql.jdbc.MysqlIO.send(MysqlIO.java:3227) 
     ... 61 more 


** END NESTED EXCEPTION ** 

Répondre

3

Cette exception suggère que vous ouvrez la Connectez-vous une seule fois au démarrage de l'application et gardez-la ouverte pour toujours pendant la durée de vie de l'application. C'est mauvais. La base de données récupèrera la connexion tôt ou tard, car elle est ouverte depuis trop longtemps. Vous devez fermer correctement les connexions dans le bloc finally du même bloc try lorsque vous l'ouvrez et exécutez la requête correspondante.

E.g.

public Entity find(Long id) throws SQLException { 
    Connection connection = null; 
    // ... 

    try { 
     connection = database.getConnection(); 
     // ... 
    } finally { 
     // ... 
     if (connection != null) try { connection.close(); } catch (SQLException logOrIgnore) {} 
    } 

    return entity; 
} 

Si vous avez un problème de performance en ce qui concerne ce (ce qui est très raisonnable que la connexion est la tâche la plus chère), alors vous devriez utiliser un pool de connexion. Il gère également de manière transparente ce genre de problèmes de "connexion interrompue". Par exemple, BoneCP. Veuillez noter que même dans le cas d'un pool de connexions, vous devez toujours fermer les connexions dans le bloc finally conformément à l'idiome de code JDBC ci-dessus. Il sera notamment les rendre disponibles pour la réutilisation.

Questions connexes