Подтвердить что ты не робот

Каков правильный способ закрыть H2?

Это связано с этим сообщением .
Я думаю, что у меня проблема с H2, что означает, что она не закрывается должным образом.
Я подозреваю это, так как я вижу myDB.lock.db, когда я завершаю tomcat, и процесс не останавливается.
Я использую пул соединений 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 Log Writer MYAPPLICATION" J9VMThread: 0x08DC6F00, j9thread_t: 0x08C9B790, java/lang/Тема: 0xE7206CC8, состояние: CW, prio = 5 3XMTHREADINFO1 (собственный идентификатор потока: 0xA32, родной приоритет: 0x5, национальная политика: UNKNOWN) 3XMTHREADINFO2
(собственный адрес стека от 0xE5E26000, до: 0xE5E67000, размер: 0x41000) 3XMTHREADINFO3 Java callstack:
4XESTACKTRACE в java/lang/Object.wait(Нативный метод)
4XESTACKTRACE на java/lang/Object.wait(Object.java:196 (скомпилированный код)) 4XESTACKTRACE в org/h2/store/WriterThread.run(WriterThread.java:102)
4XESTACKTRACE в java/lang/Thread.run(Thread.java:736)

3XMTHREADINFO "pool-8-thread-1" J9VMThread: 0x087C0200, j9thread_t: 0x0840566C, java/lang/Тема: 0xE79BFC80, состояние: P, prio = 5
3XMTHREADINFO1 (собственный идентификатор потока: 0xE1A, native приоритет: 0x5, национальная политика: UNKNOWN) 3XMTHREADINFO2
(собственный адрес стека от 0xE5F69000 до: 0xE5FAA000, размер: 0x41000) 3XMTHREADINFO3 Java callstack:
4XESTACKTRACE на солнце/разное/Unsafe.park(родной метод)
4XESTACKTRACE на Java/Util/одновременные/замки/LockSupport.park(LockSupport.java:184 (Составитель Code)) 4XESTACKTRACE at Java/Util/одновременно/замки/AbstractQueuedSynchronizer $ConditionObject.await(AbstractQueuedSynchronizer.java:1998 (Составитель Code)) 4XESTACKTRACE at Java/Util/параллельное/LinkedBlockingQueue.take(LinkedBlockingQueue.java:413 (Составитель Code)) 4XESTACKTRACE at Java/Util/параллельное/ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:958 (Составитель Code)) 4XESTACKTRACE at Java/Util/параллельный/ThreadPoolExecutor $Worker.run(ThreadPoolExecutor.java:918) 4XESTACKTRACE в java/lang/Thread.run(Thread.java:736)

3XMTHREADINFO "H2 File Lock Watchdog опт/MyOrg/кот/WebApps/MyApplication/дб/myDatabase.lock.db" J9VMThread: 0x08DC6900, j9thread_t: 0x08C9BA24, ja
va/lang/Тема: 0xE71E9018, состояние: CW, prio = 9 3XMTHREADINFO1
(собственный идентификатор потока: 0xA30, собственный приоритет: 0x9, встроенная политика: UNKNOWN)
3XMTHREADINFO2 (собственный адрес стека от 0xE5DBA000, to: 0xE5DFB000, размер: 0x41000) 3XMTHREADINFO3 Java callstack: 4XESTACKTRACE в 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.java:736)

3XMTHREADINFO "FileWatchdog" J9VMThread: 0x087C0800, j9thread_t: 0x08C9B4FC, java/lang/Тема: 0xE715D878, состояние: CW, prio = 5
3XMTHREADINFO1 (собственный идентификатор потока: 0xA2C, native приоритет: 0x5, национальная политика: UNKNOWN) 3XMTHREADINFO2
(собственный адрес стека от 0xE5E67000, до: 0xE5EA8000, размер: 0x41000) 3XMTHREADINFO3 Java callstack:
4XESTACKTRACE в java/lang/Thread.sleep(родной метод) 4XESTACKTRACE на java/lang/Thread.sleep(Thread.java:851 (Скомпилированный код)) 4XESTACKTRACE в org/apache/log4j/helpers/FileWatchdog.run(FileWatchdog.java:104)

4b9b3361

Ответ 1

В документации указано, что соединение H2 db закрывается, когда виртуальная машина выходит из строя. И это то, что он делает. Ключ завершения работы уже существует по умолчанию, вам не нужно ничего делать. Крюк выключения - вполне допустимый способ закрытия ресурсов, которые нужно закрыть только при выходе.

Если у вас есть файлы .lock.db, оставшиеся после завершения работы, виртуальная машина не выходила нормально. Вы написали, что процесс не прекращается. Вы должны найти причину этого, потому что, вероятно, это также препятствует выполнению крюка выключения H2.

С большими базами данных закрытие может занять некоторое время. См. С помощью отладчика (например, VisualVM), какие потоки остаются активными после выключения (Tomcat).

Там больше возможностей: права доступа к файлу установлены так, что H2 может создавать файлы блокировки, но не может их удалить. Если ОС не позволяет H2 удалять файлы блокировки, это не так много H2.

Ответ 2

Посмотрев на DbStarter.contextDestroyed() код (благодаря Allan5 answer), вот код, который будет работать:

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

Так что Aaron Digulla ответ был правильным (даже если не полностью "копировать/пассивно" ).

Кроме того, если вы запустили сервер H2 H2 с помощью server = Server.createTcpServer("-tcpAllowOthers"), вы можете остановить его просто с помощью server.stop().

Ответ 3

Нет, крюк отключения - это просто поток, который запускается, когда JVM завершается, независимо от того, возвращается ли он из main(), вызывая System.exit(int) или бросая исключение. Только авария JVM позволит избежать этого. См. Runtime.addShutdownHook(Thread).

Ответ 4

Не уверен, что это относится к вашей ситуации, но вы пытались добавить слушателя 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
}

Ответ 5

Вы можете выполнить оператор SHUTDOWN, а затем закрыть соединение.

Команда SHUTDOWN сделает H2 бесплатным все ресурсы, связанные с соединением немедленно. Это, например, позволит вам избавиться от встроенной базы данных H2 при повторном развертывании веб-приложения.