Каков правильный способ закрыть 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)
Ответы
Ответ 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 при повторном развертывании веб-приложения.