2012-04-02 2 views
18

Это связано с этим post.
У меня возникла проблема с H2, что означает, что она не закрывается должным образом.
Я подозреваю это, так как я вижу myDB.lock.db, когда я завершаю tomcat, и процесс не останавливается.
Я использую пул соединений Tomcat и URL-адрес в базу данных:
url="jdbc:h2:file:/opt/myOrg/tomcat/webapps/MyApplication/db/myDatabase;SCHEMA=myschema"Каков правильный способ закрыть H2?

Из дока close H2:

Обычно базы данных закрываются, когда последнее подключение к нему закрытым .. .. По умолчанию база данных закрывается, когда последнее соединение закрыто. Однако, если он никогда не будет закрыт, база данных закрываются, когда виртуальная машина выходит нормально, с помощью выключения крючка

Я не могу понять, если я делаю что-то неправильно.
Должен ли я заставлять базу данных закрываться с помощью команды? Это смысл крюка остановки?
Что я здесь делаю неправильно?

Примечание:
я не могу найти в Google пример того, как закрыть H2 правильно (кроме заявления, что он автоматически закрывается на последней остановке подключения). Должен ли я позвонить SHUTDOWN себе? Это правильный подход?
я уже вижу голосов, чтобы закрыть этот вопрос, но не было причиной или ссылку на пример того, что я расследую

UPDATE:
После Йонас Pulakka ответить дополнительные данные:

С javacore я получил с помощью kill -3 я вижу темы:

"H2 Log Writer MyApplication" J9VMThread: 0x08DC6F00, j9thread_t: 0x08C9B790, Java/языки/Th следующий образ: 0xE7206CC8, состояние: CW, PRIO = 5 3XMTHREADINFO1 (родной идентификатор потока: 0xA32, родной приоритета: 0x5, родная политика: НЕИЗВЕСТНО) 3XMTHREADINFO2
(родной стек диапазон адресов от: 0xE5E26000, чтобы: 0xE5E67000, размера: 0x41000) 3XMTHREADINFO3 Java CallStack:
4XESTACKTRACE на Java/языки/Object.wait (Native Method)
4XESTACKTRACE в Java/языки/Object.wait (Object.java:196 (скомпилированный код)) 4XESTACKTRACE в орг/h2 /store/WriterThread.run(WriterThread.java:102)
4XESTACKTRACE в java/lang/Thread.run (Thread.Java: 736)

3XMTHREADINFO "пул-8-нить-1" J9VMThread: 0x087C0200, j9thread_t: 0x0840566C, Java/языки/Автор: 0xE79BFC80, состояние: Р, PRIO = 5
3XMTHREADINFO1 (родной идентификатор потока: 0xE1A, родной приоритета: 0x5, произрастающая политика: UNKNOWN) 3XMTHREADINFO2
(родной стек диапазон адресов от: 0xE5F69000, до: 0xE5FAA000, размера: 0x41000) 3XMTHREADINFO3 Java стека вызовов:
4XESTACKTRACE на солнце/разносторонний/Unsafe.park (Нативный метод)
4XESTACKTRACE at java/util/concurrent/locks/LockSupport.park (LockSupport.java:184 (Скомпилировано)код)) 4XESTACKTRACE в Java/Util/одновременно/замки/AbstractQueuedSynchronizer $ ConditionObject.await (AbstractQueuedSynchronizer.java:1998 (Составитель код)) 4XESTACKTRACE в Java/Util/параллельный/LinkedBlockingQueue.take (LinkedBlockingQueue.java:413 (Составитель код)) 4XESTACKTRACE в Java/Util/параллельный/ThreadPoolExecutor.getTask (ThreadPoolExecutor.java:958 (Составитель код)) 4XESTACKTRACE в 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
ва/языки/Автор: 0xE71E9018, состояние: CW, ПРИО = 9 3XMTHREADINFO1
(уроженец нить ID: 0xA30, родной приоритет: 0x9, произрастающая политика: UNKNOWN)
3XMTHREADINFO2 (родной стек диапазон адресов от: 0xE5DBA000, к: 0xE5DFB000, размера: 0x41000) 3XMTHREADINFO3 Java CallStack: 4XESTACKTRACE в Java/языках/Thread .sleep (родной метод) 4XESTACKTRACE
на java/lang/Thread.sleep (Thread.java:851 (скомпилированный код))
4XESTACKTRACE на org/h2/store/Fil eLock.run (FileLock.java:490) 4XESTACKTRACE
на Java/языки/Thread.run (Thread.java:736)

3XMTHREADINFO "FileWatchdog" J9VMThread: 0x087C0800, j9thread_t: 0x08C9B4FC, Java/языки/Thread : 0xE715D878, состояние: CW, PRIO = 5
3XMTHREADINFO1 (родной идентификатор потока: 0xA2C, родной приоритет: 0x5, родная политика: НЕИЗВЕСТНО) 3XMTHREADINFO2
(родной стек диапазон адресов от: 0xE5E67000, чтобы: 0xE5EA8000, размера: 0x41000) 3XMTHREADINFO3 Java callstack:
4XESTACKTRACE на java/lang/Thread.sleep (родной метод) 4XESTACKTRACE на Java/языки/Thread.sleep (Thread.java:851 (скомпилированный код)) 4XESTACKTRACE в орг/Apache/log4j/хелперов/FileWatchdog.run (FileWatchdog.java:104)

+0

Возможный дубликат [Играть! не выключая H2 правильно] (http://stackoverflow.com/questions/7182515/play-not-shutting-down-h2-correctly) –

+0

@MohamedMansour: я прочитал этот поток, но не помог.)) I shutdown tomcat а не приложение. Таким образом, не должно быть открытых соединений. 2) Ответ кажется рабочим, и я пытаюсь понять, является ли команда «shutdown» с помощью команды SQL с помощью крючка на самом деле рекомендуемым подходом.Я не могу сказать из документа doc – Jim

+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

ответ

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-' разрешение пользователю и 'r -' разрешение на группу. Мне нужно разрешение 'x' для удаления? – Jim

+0

'x' требуется только для выполнения, а не для удаления. Но проверьте, что в каталоге нет [липкого бита] (http://www.thegeekstuff.com/2011/02/sticky-bit-on-directory-file/). –

+0

Нет никакого 't' в каталоге. И tomcat работает с использованием пользователя, который является владельцем файлов. Теперь я застрял! – Jim

1

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

+0

. Я знаю, что такое выключение. Я не могу сказать, подходит ли это для закрытия H2 – Jim

+0

@ Jim: Если вы знаете, что такое выключение, почему вы спросили: «Это означает« выключение крючка »?» –

+0

@a_horse_with_no_name: Я имел в виду в контексте смены «H2». Я не могу найти пример, показывающий, что я должен добавить крючок себя – Jim

1

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

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

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

2

Глядя на DbStarter.contextDestroyed() «кода s (благодаря Allan5» s answer), вот код, который будет работать:

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

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

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

 Смежные вопросы

  • Нет связанных вопросов^_^