2011-04-22 222 views
10

昨天AWS的RDS下跌 - 這樣做我們的數據庫。如何爲c3p0設置getConnection()超時?

這種情況發生時,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 

當我用Google搜索「socketRead0超時」和「socketRead0掛」 - 我看到了很多的問題,但沒有真正的解決方案。

有沒有辦法在這裏強制超時時間?

謝謝!

回答

3

問題出在MySQL的ReadAheadInputStream中,它使用阻塞讀取。原生套接字被阻止,永遠不會(?)返回錯誤代碼。所以連接也掛起。

我沒有看到一種方法來處理它短暫的代碼放入一個線程和加入()與超時。我不認爲這個問題證明了這個問題的合理性:我希望亞馬遜能夠從停機時間中得出正確的結論,並且不會讓它再次發生。

1

那麼,你可以在連接級別分配一個queryTimeout。 IIRC,MySQL確實服從這一點。不知道如果C3P0會喜歡它,但它可能工作。