Как установить тайм-аут getConnection () для c3p0? - PullRequest
10 голосов
/ 23 апреля 2011

Вчера RDS AWS вышел из строя, как и наша база данных.

Когда это происходило, C3P0 пытался установить соединение с базой данных и зависал. Очевидно, я бы хотел, чтобы мое приложение возвращало страницу с ошибкой в ​​этих случаях, а не просто ждал ответа вечно.

Вот как выглядит код:

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

Как установить тайм-аут для получения соединения из пула соединений c3p0?

Я думал, что это будет checkoutTimeout (), но это не так. Это «количество миллисекунд, в течение которых клиент, вызывающий getConnection (), будет ожидать подключения или получения соединения, когда пул будет исчерпан». Поскольку пул не исчерпан (он просто недоступен), это не применяется.

Я также думал, что setAcquireRetryAttempts и setAcquireIncrement будут работать - но они этого не делают, так как соединение не прерывается, оно просто не отвечает.

Когда я вытащил весь стек, вот где он останавливается:

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   

Когда я погуглил "socketRead0 timeout" и "socketRead0 hang" - я вижу много проблем, но реальных решений нет.

Есть ли способ установить здесь тайм-аут?

Спасибо!

Ответы [ 2 ]

3 голосов
/ 23 апреля 2011

Проблема в ReadAheadInputStream MySQL, которая использует блокировку чтения.Собственный сокет заблокирован и никогда (?) Не возвращает код ошибки.Так что соединение тоже зависает.

Я не вижу способа справиться с этим, если не поместить ваш код в поток и присоединиться к нему с таймаутом.Я не верю, что проблема оправдывает осложнения: я надеюсь, что Amazon сделает правильные выводы из простоя и не допустит, чтобы это повторилось.

1 голос
/ 23 апреля 2011

Ну, вы можете назначить queryTimeout на уровне соединения. IIRC, MySQL подчиняется этому. Не знаю, понравится ли C3P0, но это может сработать.

...