2012-04-02 90 views
18

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

从DOC close H2

通常,当它的最后一个连接是 关闭数据库被关闭.. ..默认情况下,关闭最后一个连接 时数据库关闭。但是,如果这是从来没有关闭,数据库时 虚拟机正常退出,用关闭挂钩

如果我做错了什么我不明白关闭。
我应该强迫数据库通过命令关闭吗?这是关机挂钩的意思吗?
我在这里做错了什么?

注:
我无法在谷歌找到如何关闭H2正确(除了它的最后一个连接关闭时自动关闭语句)的例子。我应该自己拨打SHUTDOWN吗?这是正确的方法吗?
我已经看到票关闭的问题,但没有发生过什么,我调查的一个例子的原因或链接

UPDATE:
后Joonas Pulakka回答一些额外的信息:

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

“H2日志写入MyApplication的” J9VMThread:0x08DC6F00, j9thread_t:0x08C9B790,JAVA /郎/钍读:0xE7206CC8,状态:CW,PRIO = 5 3XMTHREADINFO1(本地线程ID:0xA32,天然 优先权:0x5的,天然的策略:UNKNOWN)3XMTHREADINFO2
(本地栈地址范围从:0xE5E26000,到:0xE5E67000, 尺寸: 0x41000)3XMTHREADINFO3的Java调用堆栈:在java的
4XESTACKTRACE /郎/的Object.wait(本机方法)在 爪哇/郎/的Object.wait(Object.java:196(编译代码
4XESTACKTRACE))4XESTACKTRACE 在组织/ H2 /store/WriterThread.run(WriterThread.java:102)
4XESTACKTRACE at java/lang/Thread.run(Thread。的java:736)

3XMTHREADINFO “池-8-螺纹-1” J9VMThread:0x087C0200, j9thread_t:0x0840566C,爪哇/郎/螺纹:0xE79BFC80,状态:P,PRIO = 5
3XMTHREADINFO1(本地线程ID: 0xE1A,本地 优先级:0x5的,原生政策:未知)3XMTHREADINFO2
(本地堆栈地址范围:0xE5F69000,于:0xE5FAA000, 大小:0x41000)3XMTHREADINFO3的Java调用堆栈:在太阳/其它/ Unsafe.park
4XESTACKTRACE(本地方法)
4XESTACKTRACE java/util/concurrent/locks/LockSupport.park(LockSupport.java:184(Compiled 码))在 的Java/UTIL /并发/锁/ $的AbstractQueuedSynchronizer ConditionObject.await(AbstractQueuedSynchronizer.java:1998(编译 码))4XESTACKTRACE 4XESTACKTRACE在 的Java/UTIL /并发/ LinkedBlockingQueue.take(LinkedBlockingQueue.java:413 (编译 码))在 的Java/UTIL /并发/ ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:958(编译 码))4XESTACKTRACE 4XESTACKTRACE在 的Java/UTIL /并发/的ThreadPoolExecutor $ Worker.run(ThreadPoolExecutor.java:918 ) 4XESTACKTRACE at java/lang/Thread.run(Thread.java:736)

3XMTHREADINFO“H2 File Lock Watchdog 选择/ MYORG/Tomcat的/ web应用/所有MyApplication /分贝/ myDatabase.lock.db” J9VMThread:0x08DC6900,j9thread_t:0x08C9BA24,JA
VA /郎/螺纹:0xE71E9018,状态:CW,PRIO = 9 3XMTHREADINFO1
(本地线程ID:0xA30,天然的优先权:0x9,本地政策:UNKNOWN)
3XMTHREADINFO2(本地栈地址范围从:0xE5DBA000, 到:0xE5DFB000,尺寸:0x41000)3XMTHREADINFO3爪哇 调用堆栈:4XESTACKTRACE在 爪哇/郎/螺纹.sleep(Native Method)4XESTACKTRACE
at java/lang/Thread.sleep(Thread.java:851(Compiled Code))
4XESTACKTRACE org/h2/store/Fil eLock.run(FileLock.java:490)4XESTACKTRACE
/郎/ Thread.run(Thread.java:736)

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

+0

可能有[Play!不正确关闭H2](http://stackoverflow.com/questions/7182515/play-not-shutting-down-h2-correctly) – 2012-04-02 07:33:09

+0

@MohamedMansour:我读过那个线程,但没有帮助。1)我关闭了tomcat而不是应用程序。所以应该没有连接打开2)答案似乎是一个工作,我试图了解是否通过挂钩的SQL命令'shutdown'的力量实际上是推荐的方法。我无法从文档 – Jim 2012-04-02 07:41:49

+0

中看出H2调用['addShutdownHook()'](http://docs.oracle.com/javase/6/docs/api/java/lang/Runtime.html#addShutdownHook%28java.lang .Thread%29),使用'org.h2.engine.DatabaseCloser'的实例。 – trashgod 2012-04-02 07:49:04

回答

7

该文档显示,当虚拟机正常退出时,H2 db连接关闭。这就是它的作用。关闭挂钩已经默认存在,你不必做任何事情。关闭挂钩是关闭资源的完美有效方式,只有在退出时才需要关闭资源。

如果在关机后有剩余的.lock.db文件,那么虚拟机不会正常退出。你写的的过程不停止。你必须找到原因,因为可能这也阻止了H2关机挂钩的执行。

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

还有更多的可能性:文件权限被设置为使得H2可以创建锁文件,而不是可以删除他们。如果操作系统阻止H2删除它的锁定文件,那么H2就没有多少工作可做。

+0

谢谢。我试图调查为什么过程不停止(http://stackoverflow.com/questions/9971876/tomcat-doesnt-stop-how-can-i-debug-this),我最终在这里。同样在该文件夹中,对用户具有'rw-'权限和对组的权限。是否需要'x'权限才能删除? – Jim 2012-04-02 08:05:26

+0

'x'只用于执行,不用于删除。但请检查该目录是否设置了[sticky bit](http://www.thegeekstuff.com/2011/02/sticky-bit-on-directory-file/)。 – 2012-04-02 08:07:13

+0

不,目录中没有't'.and tomcat正在使用文件所有者的用户运行。现在我卡住了! – Jim 2012-04-02 08:13:31

1

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

+0

我知道什么是关机hook.I不知道这是否是正确的方式来关闭H2 – Jim 2012-04-02 07:39:11

+0

@Jim:如果你知道什么是关机挂钩,为什么问“*这是关机挂钩的含义?*” – 2012-04-02 07:49:47

+0

@a_horse_with_no_name:我的意思是在关闭'H2'的情况下。我无法找到一个例子来表明我应该自己添加一个钩子 – Jim 2012-04-02 07:51:12

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 
} 
1

您可以执行声明SHUTDOWN,然后关闭连接。

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

2

通过查看DbStarter.contextDestroyed()的代码(感谢Allan5answer),这里是代码,将工作:

connection.createStatement().execute("SHUTDOWN"); 

所以Aaron Digullaanswer是正确的(即使不是完全“拷贝/ pastable“)。

此外,如果您使用server = Server.createTcpServer("-tcpAllowOthers")启动H2 TCP服务器,则可以使用server.stop()简单地停止它。

相关问题