我认为我H2无法正确关闭它的意思有问题。 我怀疑这是因为我看到myDB.lock.db我关闭了tomcat,并且该过程没有停止。 我使用Tomcat的连接池,数据库的URL为: url="jdbc:h2:file:/opt/myOrg/tomcat/webapps/MyApplication/db/myDatabase;SCHEMA=myschema"
H2
myDB.lock.db
url="jdbc:h2:file:/opt/myOrg/tomcat/webapps/MyApplication/db/myDatabase;SCHEMA=myschema"
从文档中关闭H2:
通常,关闭数据库的最后一个连接时会关闭数据库。…默认情况下,关闭最后的连接时会关闭数据库。但是,如果从未关闭过数据库,则在虚拟机正常退出时使用关闭钩子关闭数据库
我无法理解我做错了什么。 是否应通过命令强制关闭数据库?这是shutdown hook的意思吗? 我在这里做错了什么?
注意: 我在Google中找不到如何H2正确关闭的示例(除了声明它在上次连接关闭时自动关闭的示例)。我应该给SHUTDOWN自己打电话吗?这是正确的方法吗? 我已经看到投票可以解决这个问题,但是我正在调查的示例没有任何原因或链接
SHUTDOWN
更新: 在乔纳斯·普拉卡(Joonas Pulakka)回答了一些额外的信息之后:
从javacore我使用a kill -3看到的线程:
javacore
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)
“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)
该文档说,虚拟机正常退出时,H2 db连接已关闭。这就是它的作用。默认情况下,关闭钩子已经存在,您无需执行任何操作。关闭钩子是关闭资源的一种完全有效的方法,该资源仅在退出时需要关闭。
如果.lock.db关闭后仍有文件剩余,则虚拟机无法正常退出。您写道 该过程不会停止 。您必须找出原因,因为这可能也阻止了H2关闭挂钩的执行。
.lock.db
对于大型数据库,关闭可能需要一些时间。查看调试器(例如VisualVM)在调用(Tomcat)关闭后哪些线程保持活动状态。
还有更多的可能性:设置文件许可权,以便H2可以 创建 锁定文件,但不能 删除 它们。如果操作系统阻止H2删除其锁定文件,则H2对此无能为力。