这与此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)
答案 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
}