关闭H2的正确方法是什么?

时间:2012-04-02 07:26:12

标签: java tomcat jdbc database-connection h2

这与此post有关 我认为我遇到问题H2意味着它没有正确关闭。
我怀疑这是因为当我关闭tomcat并且进程没有停止时我看到myDB.lock.db 我使用Tomcat的连接池,数据库的URL是:
url="jdbc:h2:file:/opt/myOrg/tomcat/webapps/MyApplication/db/myDatabase;SCHEMA=myschema"

来自文档close H2

  

通常,数据库在最后一次连接时关闭   关闭....默认情况下,数据库在最后一次连接时关闭   关闭了。但是,如果它从未关闭,则数据库将在关闭时关闭   虚拟机使用关闭挂钩正常退出

我无法理解我是否做错了什么 我应该通过命令强制关闭数据库吗?这是关机挂钩的意思吗? 我在这做错了什么?

注意:
我在Google中找不到如何正确关闭H2的示例(除了它在上次连接关闭时自动关闭的声明)。我应该自己致电SHUTDOWN吗?这是正确的方法吗? 我已经看到投票结束了这个问题,但我正在研究的一个例子没有理由或链接

更新
在Joonas Pulakka回答一些额外信息后:

javacore我使用kill -3我看到线程:

  

“H2 Log Writer MYAPPLICATION”J9VMThread:0x08DC6F00,   j9thread_t:0x08C9B790,java / lang / Thread:0xE7206CC8,状态:CW,prio = 5   3XMTHREADINFO1(本机线程ID:0xA32,本机   优先级:0x5,原生策略:UNKNOWN)3XMTHREADINFO2
  (本机堆栈地址范围从:0xE5E26000,到:0xE5E67000,   size:0x41000)3XMTHREADINFO3 Java callstack:
  java / lang / Object.wait中的4XESTACKTRACE(本机方法)
  4XESTACKTRACE at   java / lang / Object.wait(Object.java:196(Compiled Code))4XESTACKTRACE   在org / h2 / store / WriterThread.run(WriterThread.java:102)
  java / lang / Thread.run中的4XESTACKTRACE(Thread.java:736)

     

3XMTHREADINFO“pool-8-thread-1”J9VMThread:0x087C0200,   j9thread_t:0x0840566C,java / lang / Thread:0xE79BFC80,状态:P,prio = 5
  3XMTHREADINFO1(本机线程ID:0xE1A,本机   优先级:0x5,原生策略:UNKNOWN)3XMTHREADINFO2
  (本机堆栈地址范围从:0xE5F69000,到:0xE5FAA000,   size:0x41000)3XMTHREADINFO3 Java callstack:
  4XESTACKTRACE at sun / misc / Unsafe.park(Native Method)
  4XESTACKTRACE at   的java / UTIL /并发/锁/ LockSupport.park(LockSupport.java:184(编译   代码))4XESTACKTRACE at   爪哇/ UTIL /并发/锁/ $的AbstractQueuedSynchronizer ConditionObject.await(AbstractQueuedSynchronizer.java:1998(编译   代码))4XESTACKTRACE at   的java / UTIL /并发/ LinkedBlockingQueue.take(LinkedBlockingQueue.java:413(编译   代码))4XESTACKTRACE at   的java / UTIL /并发/ ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:958(编译   代码))4XESTACKTRACE at   爪哇/ UTIL /并发/的ThreadPoolExecutor $ Worker.run(ThreadPoolExecutor.java:918)   java / lang / Thread.run中的4XESTACKTRACE(Thread.java:736)

     

3XMTHREADINFO“H2文件锁看门狗   选择/ MYORG / tomcat的/ webapps /下为MyApplication / DB / myDatabase.lock.db”   J9VMThread:0x08DC6900,j9thread_t:0x08C9BA24,ja
  va / lang / Thread:0xE71E9018,状态:CW,prio = 9 3XMTHREADINFO1
  (本机线程ID:0xA30,本机优先级:0x9,本机策略:UNKNOWN)
  3XMTHREADINFO2(本机堆栈地址范围:0xE5DBA000,   to:0xE5DFB000,size:0x41000)3XMTHREADINFO3 Java   callstack:4XESTACKTRACE at   java / lang / Thread.sleep(Native方法)4XESTACKTRACE
  at java / lang / Thread.sleep(Thread.java:851(Compiled Code))
  4XESTACKTRACE at   org / h2 / store / FileLock.run(FileLock.java:490)4XESTACKTRACE
  在java / lang / Thread.run(Thread.java:736)

     

3XMTHREADINFO“FileWatchdog”J9VMThread:0x087C0800,   j9thread_t:0x08C9B4FC,java / lang / Thread:0xE715D878,状态:CW,prio = 5
  3XMTHREADINFO1(本机线程ID:0xA2C,本机   优先级:0x5,原生策略:UNKNOWN)3XMTHREADINFO2
  (本机堆栈地址范围从:0xE5E67000,到:0xE5EA8000,   size:0x41000)3XMTHREADINFO3 Java callstack:
  java / lang / Thread.sleep中的4XESTACKTRACE(本机方法)   4XESTACKTRACE at   java / lang / Thread.sleep(Thread.java:851(编译代码))4XESTACKTRACE   在org / apache / log4j / helpers / FileWatchdog.run(FileWatchdog.java:104)

5 个答案:

答案 0 :(得分:9)

文档说明当虚拟机正常退出时,H2数据库连接已关闭。这就是它的作用。默认情况下,关闭挂钩已存在,您无需执行任何操作。关闭钩子是一种完全有效的关闭资源的方法,只需要在退出时关闭。

如果关机后剩余.lock.db个文件,则虚拟机无法正常退出。您写道流程不会停止。你必须找到原因,因为这可能也阻止了H2关闭钩子的执行。

对于大型数据库,关闭可能需要一些时间。请参阅调试器(例如VisualVM),在调用(Tomcat)关闭后,哪些线程保持活动状态。

更有可能:设置文件权限以便H2可以创建锁文件,但不能删除它们。如果操作系统阻止H2删除其锁定文件,那么H2就无法做到这一点。

答案 1 :(得分:4)

您可以执行语句SHUTDOWN,然后关闭连接。

SHUTDOWN命令将使H2立即释放与连接相关的所有资源。例如,这将允许您在重新部署Web应用程序时删除嵌入式H2数据库。

答案 2 :(得分:4)

通过查看DbStarter.contextDestroyed()的代码(感谢Allan5' s answer),以下是可行的代码:

server = Server.createTcpServer("-tcpAllowOthers")

所以Aaron Digulla' answer是正确的(即使不完全"复制/匹配")。

此外,如果您使用server.stop()启动了H2 TCP服务器,则只需使用Authorization: INSERT_YOUR_TOKEN_HERE 即可停止使用。

答案 3 :(得分:1)

不,关闭挂钩只是一个在JVM终止时运行的线程,无论是从main()返回,调用System.exit(int)还是抛出异常。只有JVM崩溃才能避免它。请参阅Runtime.addShutdownHook(Thread)。

答案 4 :(得分:1)

不确定这是否与您的情况相关,但您是否尝试过添加DBStarter侦听器?

http://www.h2database.com/html/tutorial.html,请参阅“使用Servlet侦听器启动和停止数据库”部分。

该链接建议将以下内容添加到web.xml:

<listener>
    <listener-class>org.h2.server.web.DbStarter</listener-class>
</listener>

请参阅此处的讨论(诚然从2008年开始,因此可能已过期) - 显然此修复程序适用于嵌入式和非嵌入式实例:http://groups.google.com/group/h2-database/browse_thread/thread/eb609d58c96f4317

或者您如何使用连接?你确定要正确清理连接吗?

之前我遇到过问题,在我的情况下,我使用了与JPA EntityManager的连接,我忘了在使用后关闭EntityManager实例,这导致了一些问题:

@PersistenceUnit(unitName="myEm")
private EntityManagerFactory emf;

public void doStuff() {
    EntityManager em = emf.createEntityManager();
    ...
    em.close(); // forgot this line
}