[英]Servlet's destroy method isn't closing the DB connection even thought I told it too
所以我有一個每分鍾查詢數據庫的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方式編寫它...
根據文檔,只有在servlet中的所有線程都退出或發生超時后才會調用destroy()
。 所以理論上應該始終調用destroy,除非容器沒有優雅地停止。
destroy()
方法中沒有例外 此外,如果您使用舊版本的Tomcat,請注意此錯誤
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之前的版本)。
如果您正在使用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
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.