简体   繁体   English

如何为c3p0设置getConnection()超时?

[英]How to set a getConnection() timeout for c3p0?

Yesterday AWS's RDS went down -- and so did our database. 昨天AWS的RDS下降了 - 我们的数据库也是如此。

When this happened, C3P0 would try to get a database connection and would hang. 发生这种情况时,C3P0会尝试获取数据库连接并挂起。 I would obviously like my application to return an error page in these instances, rather than just waiting forever for a response. 我显然希望我的应用程序在这些实例中返回错误页面,而不是仅仅等待响应。

Here's what the code looks like: 这是代码的样子:

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

How can set a timeout for getting a connection from c3p0's connection pool? 如何设置从c3p0的连接池获取连接的超时?

I thought checkoutTimeout() would be it -- but it's not. 我以为checkoutTimeout()就是它 - 但事实并非如此。 It is "the number of milliseconds a client calling getConnection() will wait for a Connection to be checked-in or acquired when the pool is exhausted." 它是“当池耗尽时,客户端调用getConnection()将等待连接被签入或获取的毫秒数。” Since the pool in not exhausted (it is just unavailable) this does not apply. 由于池没有用尽(它只是不可用),这不适用。

I also thought setAcquireRetryAttempts and setAcquireIncrement would work -- but they do not since a connection doesn't fail, it just doesn't respond. 我还认为setAcquireRetryAttempts和setAcquireIncrement可以工作 - 但是它们不会因为连接没有失败,所以它只是没有响应。

When I pulled the whole stack, this is where it stalls: 当我拉动整个堆栈时,这就是它停止的地方:

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   

When I googled "socketRead0 timeout" and "socketRead0 hang" -- I see a lot of problems but no real solutions. 当我搜索“socketRead0 timeout”和“socketRead0 hang”时 - 我看到很多问题,但没有真正的解决方案。

Is there any way to force a timeout period here? 有没有办法在这里强制超时?

Thanks! 谢谢!

The issue is within MySQL's ReadAheadInputStream, which uses blocking read. 问题出在MySQL的ReadAheadInputStream中,它使用阻塞读取。 Native socket got blocked and never(?) returns an error code. 本机套接字被阻止,从不(?)返回错误代码。 So the connection hangs too. 所以连接也挂起了。

I do not see a way to handle it short of placing your code into a thread and join() to it with timeout. 我没有看到一种方法来处理它,而不是将代码放入线程并使用超时join()。 I do not believe though the problem justifies the complications: I hope Amazon will make the right conclusions from the downtime, and won't let it happen again. 我不相信这个问题可以证明并发症:我希望亚马逊能够从停机时间得出正确的结论,并且不会让它再次发生。

Well, you can assign a queryTimeout at the connection level. 好吧,您可以在连接级别分配queryTimeout。 IIRC, MySQL does obey this. IIRC,MySQL确实遵守这一点。 Dunno if C3P0 will like it, but it might work. Dunno如果C3P0会喜欢它,但它可能会奏效。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM