web-dev-qa-db-ja.com

H2を閉じる適切な方法は何ですか?

これはこれに関連しています post
H2が適切に閉じないという問題が発生していると思います。
TomcatをシャットダウンしたときにmyDB.lock.dbが表示され、プロセスが停止しないため、これが疑われます。
私はTomcatの接続プールを使用しており、データベースへのURLは次のとおりです。
url="jdbc:h2:file:/opt/myOrg/Tomcat/webapps/MyApplication/db/myDatabase;SCHEMA=myschema"

ドキュメントから H2を閉じる

通常、データベースは、最後の接続が閉じられると閉じられます。デフォルトでは、データベースは最後の接続が閉じられると閉じられます。ただし、データベースが閉じられていない場合、仮想マシンが正常に終了すると、シャットダウンフックを使用してデータベースが閉じられます。

何か悪いことをしているかわかりません。
コマンドを使用してデータベースを強制的に閉じる必要がありますか?これはシャットダウンフックの意味ですか?
ここで何が悪いのですか?

注:
GoogleでH2を適切に閉じる方法の例が見つかりません(最後の接続のシャットダウン時に自動的に閉じるというステートメントのほかに)。 SHUTDOWNを自分で呼ぶべきですか?これは適切なアプローチですか?
質問を閉じるための投票はすでにありますが、調査している例の理由やリンクがありません

UPDATE:
Joonas Pulakkaが追加情報に回答した後:

javacoreから、kill -3を使用してスレッドを確認しました。

"H2ログライターMYAPPLICATION" J9VMThread:0x08DC6F00、j9thread_t:0x08C9B790、Java/lang/Thread:0xE7206CC8、state:CW、prio = 5 3XMTHREADINFO1(ネイティブスレッドID:0xA32、ネイティブプライオリティ:0x5、ネイティブポリシー:UNKNOWN2)3XMTHREADINFO
(ネイティブスタックアドレス範囲:0xE5E26000から0xE5E67000、サイズ:0x41000)3XMTHREADINFO3 Javaコールスタック:
4XESTACKTRACE at Java/lang/Object.wait(Native Method)
4XESTACKTRACE at Java/lang/Object.wait(Object.Java:196(Compiled Code))4XESTACKTRACE at org/h2/store/WriterThread.run(WriterThread.Java:102)
Java/lang/Thread.run(Thread.Java:736)の4XESTACKTRACE

3XMTHREADINFO "pool-8-thread-1" J9VMThread:0x087C0200、j9thread_t:0x0840566C、Java/lang/Thread:0xE79BFC80、state:P、prio = 5
3XMTHREADINFO1(ネイティブスレッドID:0xE1A、ネイティブプライオリティ:0x5、ネイティブポリシー:UNKNOWN)3XMTHREADINFO2
(ネイティブスタックアドレス範囲:0xE5F69000から、:0xE5FAA000、サイズ:0x41000)3XMTHREADINFO3 Java callstack:
4XESTACKTRACE at Sun/misc/Unsafe.park(Native Method)
4XESTACKTRACE at Java/util/concurrent/locks/LockSupport.park(LockSupport.Java:184(Compiled Code))4XESTACKTRACE at Java/util/concurrent/locks/AbstractQueuedSynchronizer $ ConditionObject.await(AbstractQueuedSynchronizer.Java:1998 (コンパイル済みコード))4XESTACKTRACE at Java/util/concurrent/LinkedBlockingQueue.take(LinkedBlockingQueue.Java:413(Compiled Code))4XESTACKTRACE at Java/util/concurrent/ThreadPoolExecutor.getTask(ThreadPoolExecutor.Java:958(Compiled Code))4XESTACKTRACE Java/util/concurrent/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、state:CW、prio = 9 3XMTHREADINFO1
(ネイティブスレッドID:0xA30、ネイティブプライオリティ:0x9、ネイティブポリシー:UNKNOWN)
3XMTHREADINFO2(ネイティブスタックアドレス範囲:0xE5DBA000、〜:0xE5DFB000、サイズ:0x41000)3XMTHREADINFO3 Java callstack:4XESTACKTRACE at Java/lang/Thread.sleep(Native Method)4XESTACKTRACE
at Java/lang/Thread.sleep(Thread.Java:851(Compiled Code))
org/h2/store/FileLock.run(FileLock.Java:490)の4XESTACKTRACE 4XESTACKTRACE
at Java/lang/Thread.run(Thread.Java:736)

3XMTHREADINFO "FileWatchdog" J9VMThread:0x087C0800、j9thread_t:0x08C9B4FC、Java/lang/Thread:0xE715D878、state:CW、prio = 5
3XMTHREADINFO1(ネイティブスレッドID:0xA2C、ネイティブプライオリティ:0x5、ネイティブポリシー:UNKNOWN)3XMTHREADINFO2
(ネイティブスタックアドレス範囲:0xE5E67000、〜:0xE5EA8000、サイズ:0x41000)3XMTHREADINFO3 Javaコールスタック:
4XESTACKTRACE at Java/lang/Thread.sleep(Native Method)4XESTACKTRACE at Java/lang/Thread.sleep(Thread.Java:851(Compiled Code))4XESTACKTRACE at org/Apache/log4j/helpers/FileWatchdog run(FileWatchdog.Java:104)

24
Jim

ドキュメントには、仮想マシンが正常に終了するとH2 db接続が閉じられると記載されています。そしてそれはそれがすることです。シャットダウンフックはデフォルトですでに存在しています。何もする必要はありません。シャットダウンフックは、終了時にのみ閉じる必要があるリソースを閉じるための完全に有効な方法です。

あなたが持っている場合 .lock.dbシャットダウン後にファイルが残っていると、仮想マシンが正常に終了しませんでした。 プロセスは停止しませんと書きました。その理由を見つける必要があります。これは、おそらくH2シャットダウンフックの実行も妨げているためです。

大きなデータベースでは、閉じるのに時間がかかる場合があります。デバッガー(VisualVMなど)を使用して、(Tomcat)シャットダウンを呼び出した後もアクティブなスレッドを確認します。

より多くの可能性があります:H2が作成ファイルをロックできるが削除できないようにファイル権限が設定されています。 OSがH2がロックファイルを削除できないようにする場合、H2ができることはほとんどありません。

9
Joonas Pulakka

DbStarter.contextDestroyed() のコード( Allan5answer に感謝)を見ると、次のコードになります作業:

_connection.createStatement().execute("SHUTDOWN");
_

つまり Aaron Digullaanswer は正しかった(完全に「コピー/貼り付け可能」でなくても)。

さらに、server = Server.createTcpServer("-tcpAllowOthers")を使用してH2 TCPサーバーを起動した場合は、server.stop()を使用して停止できます。

4
Anthony O.

ステートメントSHUTDOWNを実行して、接続を閉じることができます。

SHUTDOWNコマンドは、H2に接続に関連するすべてのリソースをすぐに解放させます。これにより、たとえば、Webアプリケーションを再デプロイするときに、埋め込まれたH2データベースを削除できます。

4
Aaron Digulla

これがあなたの状況に関連しているかどうかはわかりませんが、DBStarterリスナーを追加してみましたか?

http://www.h2database.com/html/tutorial.html 、「サーブレットリスナーを使用したデータベースの起動と停止」セクションを参照してください。

リンクは、以下を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
}
2
Allan5

いいえ、シャットダウンフックは、main()から戻ったり、System.exit(int)を呼び出したり、例外をスローしたりしても、JVMの終了時に実行される単なるスレッドです。 JVMクラッシュのみがそれを回避します。 Runtime.addShutdownHook(Thread)を参照してください。