これは、次の 2 つの投稿に関連しています。
基本的に、H2 はすべての接続が閉じられている場合でもデータベースのロックを保持するため、Tomcat を停止するとスレッドで待機してハングし、プロセスは引き続き実行されます。H2 がデータベースをロックしないようにする唯一の方法は、ステートメントSHUTDOWN IMMEDIATELY
コマンドを発行することです (バニラまたはcompact
ロックを解放しませんでした)。
これは、 contextDestroyed の ServletContextListener クラスで次のように実行されます (コメントとログ行を省略しました)。
ServletContext ctx = servletContextEvent.getServletContext();
DataSource closeDS = databaseConnection.getDatasource();
Connection closeConn = null;
PreparedStatement closePS = null;
try {
closeConn = closeDS.getConnection();
closePS = closeConn.prepareStatement("SHUTDOWN IMMEDIATELY");
closePS.execute();
} catch (Exception ex) {
} finally {
if (closePS != null) {
try { closePS.close(); } catch (SQLException ex) {}
}
if (closeConn != null) {
try { closeConn.close(); } catch (SQLException ex) {}
}
}
try {
databaseConnection.close();
databaseConnection = null;
ctx.setAttribute("databaseConnection", null);
} catch(Exception e) {
}
Enumeration<Driver> drivers = DriverManager.getDrivers();
while (drivers.hasMoreElements()) {
Driver driver = drivers.nextElement();
try {
DriverManager.deregisterDriver(driver);
} catch (Exception e) {
}
}
これでロックが解除され、Tomcat が停止します (ただし、ログに重大なメモリ リーク メッセージが表示されます) が、ログに多数のエラー スタックも表示されるようになりました。
INFO: Illegal access: this web application instance has been stopped already.
Could not load java.lang.ThreadGroup.
The eventual following stack trace is caused by an error thrown
for debugging purposes as well as to attempt to terminate
the thread which caused the illegal access, and has no functional impact.
java.lang.IllegalStateException
at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1531)
at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1491)
at org.h2.engine.DatabaseCloser.reset(DatabaseCloser.java:43)
at org.h2.engine.Database.close(Database.java:1155)
at org.h2.engine.DatabaseCloser.run(DatabaseCloser.java:80)
10-sep-2013 13:31:41 org.apache.catalina.loader.WebappClassLoader loadClass
問題は、不正な状態例外を発生させずにデータベースをシャットダウンするにはどうすればよいかということです。シャットダウン コマンドを呼び出すコードに何か問題がありますか? なぜこれが H2 でこのような問題になるのですか? コンテナーによって提供されるデータソースを使用してアプリケーションも実行される JBoss または Websphere では、この問題は発生しません。