在我的java代码中,我正在处理大量的数据。因此,我将代码作为servlet转移到应用程序引擎的CronJob中。有时效果很好。数据量增加后,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)
如何处理这个问题?
当多个线程之间共享单个连接时,此异常是典型的。当您的代码不遵循标准JDBC习惯用法,即在尽可能短的范围内获取并关闭相同try-finally
块中的DB资源时,就会发生这种情况,如下所示:
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()
方法中获得一个DB连接,并在所有HTTP会话中的所有HTTP请求中重用同一个连接。这是绝对不对的。servlet实例在webapp启动期间只创建/初始化一次,并在应用程序的整个剩余生命周期中重复使用。这至少证实了你所面临的例外。
只要按照上面演示的标准try-finally
习惯用法重写JDBC代码,您就应该做好了准备。
另请参阅:
- 在多线程系统中使用静态java.sql.Connection实例安全吗