一尘不染

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

tomcat

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

从文档中关闭H2

通常,关闭数据库的最后一个连接时会关闭数据库。…默认情况下,关闭最后的连接时会关闭数据库。但是,如果从未关闭过数据库,则在虚拟机正常退出时使用关闭钩子关闭数据库

我无法理解我做错了什么。
是否应通过命令强制关闭数据库?这是shutdown hook的意思吗?
我在这里做错了什么?

注意:
我在Google中找不到如何H2正确关闭的示例(除了声明它在上次连接关闭时自动关闭的示例)。我应该给SHUTDOWN自己打电话吗?这是正确的方法吗?
我已经看到投票可以解决这个问题,但是我正在调查的示例没有任何原因或链接

更新:
在乔纳斯·普拉卡(Joonas Pulakka)回答了一些额外的信息之后:

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

“H2日志写入所有MyApplication”
J9VMThread:0x08DC6F00,j9thread_t:0x08C9B790,爪哇/郎/螺纹:0xE7206CC8,状态:CW,PRIO =
5 3XMTHREADINFO1(本地线程ID:0xA32,天然的优先权:0x5的,天然的策略:UNKNOWN)3XMTHREADINFO2
(天然堆栈地址范围从:0xE5E26000到:0xE5E67000,大小:0x41000)3XMTHREADINFO3 Java调用
栈:java / lang / Object.wait(本机方法)为
4XESTACKTRACE,java / lang / Object.wait(Object.java:196(编译代码)为4XESTACKTRACE
))4XESTACKTRACE at org / h2 / store /
WriterThread.run(WriterThread.java:102)
4XESTACKTRACE at java / lang / Thread.run(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,大小:0x41000)3XMTHREADINFO3 Java调用
栈:sun / misc / Unsafe.park处的4XESTACKTRACE(本机方法)
java / util / concurrent / locks /
LockSupport.park上的4XESTACKTRACE(LockSupport.java:184(编译代码))java / util /
concurrent / locks / AbstractQueuedSynchronizer $
ConditionObject.await上的4XESTACKTRACE(AbstractQueuedSynchronizer.java:1998(编译代码))
java / util / concurrent /
LinkedBlockingQueue.take(LinkedBlockingQueue.java:413(编译代码))处的4XESTACKTRACE
java / util / concurrent /
ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:958(Compiled
Code))处的4XESTACKTRACE parallel / ThreadPoolExecutor $
Worker.run(ThreadPoolExecutor.java:918)4XESTACKTRACE at java / lang /
Thread.run(Thread.java:736)

3XMTHREADINFO“ H2文件锁监视程序opt / 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到:0xE5DFB000,大小:0x41000)3XMTHREADINFO3
Java调用栈:java / lang / Thread.sleep(本机方法为4XESTACKTRACE) )
java / lang / Thread.sleep(Thread.java:851(编译代码)处的
4XESTACKTRACE)org / h2 / store / FileLock.run(FileLock.java:490)
处的4XESTACKTRACE(java / lang / Thread.run(Thread )处的4XESTACKTRACE .java:736)

3XMTHREADINFO “FileWatchdog”
J9VMThread:0x087C0800,j9thread_t:0x08C9B4FC,爪哇/郎/螺纹:0xE715D878,状态:CW,PRIO =
5
3XMTHREADINFO1(本地线程ID:0xA2C,天然的优先权:0x5的,天然的策略:UNKNOWN)3XMTHREADINFO2
(本地栈地址范围从:0xE5E67000到:0xE5EA8000,大小:0x41000)3XMTHREADINFO3 Java调用堆栈:
java / lang / Thread.sleep(本机方法)为4XESTACKTRACE,java / lang /
Thread.sleep(Thread.java:851(编译代码))为4XESTACKTRACE 4XESTACKTRACE,位于org /
apache / log4j / helpers / FileWatchdog.run(FileWatchdog.java:104)


阅读 490

收藏
2020-06-16

共1个答案

一尘不染

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

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

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

还有更多的可能性:设置文件许可权,以便H2可以 创建 锁定文件,但不能 删除 它们。如果操作系统阻止H2删除其锁定文件,则H2对此无能为力。

2020-06-16