所以我有一个每分钟查询数据库的servlet,所以我想我将永远打开一个连接(好吧,直到webapp停止)。因此我在init()中打开一个连接并在destroy()中关闭它。事实是,如果我在tomcat中停止应用程序后查看数据库,则连接仍处于打开状态。发生了什么事?
这是我的代码:
public void init() throws ServletException
{
try
{
// Prepare the DB connection
DriverManager.registerDriver(new com.informix.jdbc.IfxDriver());
informixConnection = DriverManager.getConnection(DBURL, DBUsername, DBPassword);
}
catch(SQLException e)
{
throw new UnavailableException("Error connecting to the database");
}
}
public void destroy()
{
try
{
informixConnection.close();
}
catch(Exception e)
{
}
}
还会有一个实际执行查询的方法,以及一个doGet,以便用户可以获得最新的响应,但我还没有完成这些(虽然我已经测试过它们并且数据库连接有效)。
我不知道为什么这不起作用。我在destroy方法中添加了一些日志记录,以确认在应用程序关闭时它被调用,突然它开始工作了。怪异。
好的,现在去用非servlet方式编写它......
答案 0 :(得分:2)
根据文档,只有在servlet中的所有线程都退出或发生超时后才会调用destroy()
。所以理论上应该始终调用destroy,除非容器没有优雅地停止。
destroy()
方法此外,如果您使用旧版本的Tomcat,请注意此bug
答案 1 :(得分:0)
init()和destroy()方法与Servlet的生命周期相关联。
典型servlet的生命周期是容器中应用程序的生命周期。
在正常情况下,对于通用servlet,应用程序将部署到容器,并启动应用程序。此时,servlet不存在。
一旦请求被定向到映射到Servlet的URL,容器就会检查它是否还没有启动该Servlet的实例。如果没有,它将调用Servlet上的init()方法,然后开始向它发送路由请求。通常,应用程序中一次只有一个Servlet实例。
作为替代方案,可以在web.xml中使用load-on-startup参数配置Servlet,如果存在,则在应用程序启动期间初始化Servlet,而不是等待初始化Servlet的请求。
稍后,当容器关闭或应用程序取消部署时,容器将在应用程序生命周期内初始化的任何Servlet上调用destroy()方法。
因此,总而言之,如果您希望将init()和destroy()方法绑定到各个请求,那么您的期望就会错位。为此,你会看到一个ServletRequestListener(Servlet 3.0),或使用Servlet过滤器(3.0之前的版本)的特殊内容。
答案 2 :(得分:0)
如果您正在使用Tomcat,则可以创建资源
<Resource name="jdbc/AutoOracle"
auth="Container"
type="javax.sql.DataSource"
driverClassName="oracle.jdbc.driver.OracleDriver"
username="usrname"
password="pswd"
url="jdbc:oracle:thin:@yourdb:1521:yourdb"
maxActive="1500"
maxIdle="30"
maxWait="5000"
removeAbandoned="true"
removeAbandonedTimeout="900"
timeBetweenEvictionRunsMillis="300000"
minEvictableIdleTimeMillis="1800000"
testOnBorrow="true"
testWhileIdle="true"
validationQuery="select 'test' from Dual"
validationQueryTimeout="3"
/>
在servlet中创建一个Context
Context dataSourceContext = new InitialContext();
然后使用上下文在需要连接的方法内创建数据库连接。
Connection conn = null;
try{
DataSource ds = (DataSource)ctx.lookup("java:comp/env/jdbc/AutoOracle");
conn = ds.getConnection();
if(conn == null){
log.error("Connection is null");
}else{
// do some work
}
}catch(Exception e){
// handle exceptions
}finally{
try{
conn.close();
}catch(Exception e){
// handle exception
}
}