java.sql.SQLRecoverableException:连接已在使用中

时间:2012-09-26 04:54:06

标签: google-app-engine servlets jdbc sqlexception google-cloud-sql

在我的java代码中,我正在处理大量数据。所以我将代码作为servlet移动到App Engine的Cron Job。有些日子它工作正常。数据量增加后,cron作业无法正常工作,并显示以下错误消息。

2012-09-26 04:18:40.627
'ServletName' 'MethodName': Inside SQLExceptionjava.sql.SQLRecoverableException: 
    Connection is already in use.

I 2012-09-26 04:18:40.741
This request caused a new process to be started for your application, and thus caused 
your application code to be loaded for the first time. This request may thus take 
longer and use more CPU than a typical request for your application.

W 2012-09-26 04:18:40.741
A problem was encountered with the process that handled this request, causing it to 
exit. This is likely to cause a new process to be used for the next request to your 
application. If you see this message frequently, you may be throwing exceptions during 
the initialization of your application. (Error code 104)

如何处理这个问题?

1 个答案:

答案 0 :(得分:0)

在多个线程之间共享单个连接时,通常会出现此异常。当你的代码遵循标准的JDBC习惯用法时,这将在同一个try-finally块中以尽可能短的范围获取和关闭数据库资源,这样就会发生这种情况:

public Entity find(Long id) throws SQLException {
    Connection connection = null; 
    // ...

    try {
        connection = dataSource.getConnection();
        // ...
    } finally {
        // ...
        if (connection != null) try { connection.close(); } catch (SQLException ignore) {}
    }

    return entity;
}

您对此问题的评论,

  

@TejasArjun我使用了与servlet Init()方法的连接池。

并不会让我觉得你正确地做到了这一点。这表明您正在使用servlet的init()方法获取数据库连接,并在所有HTTP会话中的所有HTTP请求中重用相同的连接。这绝对不对。 servlet实例仅在webapp启动期间创建/初始化一次,并在整个应用程序生命周期的剩余时间内重用。这至少证实了你所面临的例外。

根据上面演示的标准try-finally惯用法重写您的JDBC代码,您应该全部设置。

另见: