2011-04-22 5 views
10

Hier, le RDS d'AWS est tombé en panne, tout comme notre base de données. Lorsque cela arrivait, C3P0 essayait d'obtenir une connexion à la base de données et se bloquait. Je voudrais évidemment que mon application retourne une page d'erreur dans ces cas, plutôt que d'attendre une réponse pour toujours.Comment définir un délai d'attente getConnection() pour c3p0?

Voici ce que le code ressemble à:

ComboPooledDataSource db = new ComboPooledDataSource(); 
... 
Connection conn = db.getConnection(); 

Comment définir un délai d'attente pour obtenir une connexion à partir du pool de connexion de C3P0?

Je pensais que checkoutTimeout() le serait - mais ce n'est pas le cas. C'est "le nombre de millisecondes qu'un client appelle getConnection() attendra qu'une Connexion soit enregistrée ou acquise lorsque le pool est épuisé." Puisque la piscine n'est pas épuisée (c'est juste indisponible) cela ne s'applique pas.

Je pensais aussi que setAcquireRetryAttempts et setAcquireIncrement fonctionneraient - mais ils ne fonctionnent pas car une connexion n'échoue pas, elle ne répond pas.

Quand j'ai tiré l'ensemble de la pile, c'est là il cale:

SocketInputStream.socketRead0(FileDescriptor, byte[], int, int, int) line: not available [native method]  
SocketInputStream.read(byte[], int, int) line: 129 
ReadAheadInputStream.fill(int) line: 113  
ReadAheadInputStream.readFromUnderlyingStreamIfNecessary(byte[], int, int) line: 160  
ReadAheadInputStream.read(byte[], int, int) line: 188 
MysqlIO.readFully(InputStream, byte[], int, int) line: 2428 
MysqlIO.reuseAndReadPacket(Buffer, int) line: 2882 
MysqlIO.reuseAndReadPacket(Buffer) line: 2871 
MysqlIO.checkErrorPacket(int) line: 3414  
MysqlIO.sendCommand(int, String, Buffer, boolean, String) line: 1936  
MysqlIO.sqlQueryDirect(StatementImpl, String, String, Buffer, int, int, int, boolean, String, Field[]) line: 2060 
JDBC4Connection(ConnectionImpl).execSQL(StatementImpl, String, int, Buffer, int, int, boolean, String, Field[], boolean) line: 2542 
JDBC4PreparedStatement(PreparedStatement).executeInternal(int, Buffer, boolean, boolean, Field[], boolean) line: 1734 
JDBC4PreparedStatement(PreparedStatement).executeQuery() line: 1885 
NewProxyPreparedStatement.executeQuery() line: 76 
C3P0PooledConnectionPoolManager.initializeAutomaticTestTable(String, DbAuth) line: 799 
C3P0PooledConnectionPoolManager.createPooledConnectionPool(DbAuth) line: 696  
C3P0PooledConnectionPoolManager.getPool(DbAuth) line: 257 
C3P0PooledConnectionPoolManager.getPool() line: 271 
ComboPooledDataSource(AbstractPoolBackedDataSource).getNumThreadsAwaitingCheckoutDefaultUser() line: 203  
NativeMethodAccessorImpl.invoke0(Method, Object, Object[]) line: not available [native method] 
NativeMethodAccessorImpl.invoke(Object, Object[]) line: 39 
DelegatingMethodAccessorImpl.invoke(Object, Object[]) line: 25 
Method.invoke(Object, Object...) line: 597 
BeansUtils.extractAccessiblePropertiesToMap(Map, Object, Collection) line: 359 
BeansUtils.appendPropNamesAndValues(StringBuffer, Object, Collection) line: 324 
ComboPooledDataSource.toString() line: 539 
ComboPooledDataSource(AbstractPoolBackedDataSource).getPoolManager() line: 462 
ComboPooledDataSource(AbstractPoolBackedDataSource).getConnection() line: 128 

Quand je googlé « délai d'attente socketRead0 » et « socketRead0 coup » - Je vois beaucoup de problèmes, mais pas de véritables solutions.

Y a-t-il un moyen de forcer une période de temporisation ici?

Merci!

Répondre

3

Le problème est dans ReadAheadInputStream de MySQL, qui utilise la lecture bloquante. La socket native a été bloquée et never (?) Renvoie un code d'erreur. Donc, la connexion est suspendue aussi.

Je ne vois pas un moyen de le gérer à court de placer votre code dans un thread et joindre() avec timeout. Je ne crois pas que le problème justifie les complications: j'espère qu'Amazon tirera les bonnes conclusions du temps d'arrêt et ne laissera pas cela se reproduire.

1

Eh bien, vous pouvez affecter un queryTimeout au niveau de la connexion. IIRC, MySQL obéit à cela. Dunno si C3P0 va l'aimer, mais ça pourrait marcher.

Questions connexes