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

发布于 2024-11-03 05:59:18 字数 2837 浏览 4 评论 0原文

昨天,AWS 的 RDS 宕机了,我们的数据库也宕机了。

发生这种情况时,C3P0 将尝试获取数据库连接并挂起。我显然希望我的应用程序在这些情况下返回错误页面,而不是永远等待响应。

代码如下:

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

How can set a timeout for getting a connection from c3p0's Connection Pool?

我以为 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”和“socketRead0hang”时——我看到了很多问题,但没有真正的解决方案。

这里有什么办法强制超时吗?

Yesterday AWS's RDS went down -- and so did our database.

When this happened, C3P0 would try to get a database connection and would hang. 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?

I thought checkoutTimeout() would be it -- but it's not. 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." 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.

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.

Is there any way to force a timeout period here?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

好菇凉咱不稀罕他 2024-11-10 05:59:18

问题出在 MySQL 的 ReadAheadInputStream 中,它使用阻塞读取。本机套接字被阻止并且从不(?)返回错误代码。所以连接也挂起。

除了将代码放入线程中并在超时的情况下 join() 到它之外,我没有找到处理它的方法。我不认为这个问题可以证明复杂性是合理的:我希望亚马逊能够从停机中得出正确的结论,并且不会让这种情况再次发生。

The issue is within MySQL's ReadAheadInputStream, which uses blocking read. 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. 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.

诠释孤独 2024-11-10 05:59:18

那么,您可以在连接级别分配一个 queryTimeout。 IIRC,MySQL 确实遵守这一点。不知道 C3P0 是否会喜欢它,但它可能会起作用。

Well, you can assign a queryTimeout at the connection level. IIRC, MySQL does obey this. Dunno if C3P0 will like it, but it might work.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文