2012-04-02 50 views
18

Esto se relaciona con este post.
Creo que tengo problemas con H2, lo que significa que no se cierra correctamente.
Sospecho esto porque veo myDB.lock.db cuando cierro tomcat y el proceso no se detiene.
que utilizan la agrupación de conexiones de Tomcat y la url a la base de datos es:
url="jdbc:h2:file:/opt/myOrg/tomcat/webapps/MyApplication/db/myDatabase;SCHEMA=myschema"¿Cuál es la forma correcta de cerrar H2?

Desde el doc close H2:

Por lo general, una base de datos se cierra cuando la última conexión con él es cerrada .. .. Por defecto, una base de datos se cierra cuando se cierra la última conexión . Sin embargo, si no se cierra nunca, la base de datos se cierra cuando la máquina virtual sale normalmente, usando un gancho de cierre

No puedo entender si estoy haciendo algo mal.
¿Debo forzar que la base de datos se cierre mediante un comando? ¿Es este el significado de shutdown hook?
¿Qué estoy haciendo mal aquí?

Nota:
no puedo encontrar en Google un ejemplo de cómo cerrar adecuadamente H2 (además de la declaración de que se cierre automáticamente en la última parada de la conexión). ¿Debería llamar al SHUTDOWN? ¿Es este el enfoque adecuado?
ya veo califican para cerrar la pregunta, pero no ha habido una razón o enlace en un ejemplo de lo que estoy investigando

ACTUALIZACIÓN:
Después de Joonas Pulakka contestar algo de información extra:

De la javacore que tiene el uso de un kill -3 veo los hilos:

"H2 Entrar escritor MyApplication" J9VMThread: 0x08DC6F00, j9thread_t: 0x08C9B790, java/lang/Th leer: 0xE7206CC8, Estado: CW, prio = 5 3XMTHREADINFO1 (ID hilo nativo: 0xA32, nativo prioridad: 0x5, la política nativa: desconocido) 3XMTHREADINFO2
(rango de dirección de pila nativa a partir de: 0xE5E26000, a: 0xE5E67000, tamaño: 0x41000) 3XMTHREADINFO3 pila de llamadas Java:
4XESTACKTRACE en java/lang/Object.wait (nativo Método)
4XESTACKTRACE en java/lang/Object.wait (Object.java:196 (Compilado Código)) 4XESTACKTRACE en org/h2 /store/WriterThread.run(WriterThread.java:102)
4XESTACKTRACE en java/lang/Thread.run (Thread.java: 736)

3XMTHREADINFO "pool-8-thread-1" J9VMThread: 0x087C0200, j9thread_t: 0x0840566C, java/lang/Tema: 0xE79BFC80, Estado: P, prio = 5
3XMTHREADINFO1 (ID hilo nativo: 0xE1A, nativo prioridad: 0x5, la política nativa: DESCONOCIDO) 3XMTHREADINFO2
(rango de direcciones pila nativa de: 0xE5F69000, a: 0xE5FAA000, tamaño: 0x41000) 3XMTHREADINFO3 Java pila de llamadas:
4XESTACKTRACE al sol/misc/Unsafe.park (Método nativo)
4XESTACKTRACE en java/util/concurrent/locks/LockSupport.park (LockSupport.java:184 (Compiled)Código)) 4XESTACKTRACE en java/util// cerraduras/AbstractQueuedSynchronizer $ ConditionObject.await (AbstractQueuedSynchronizer.java:1998 (Compilado Código)) 4XESTACKTRACE concurrente en java/util/concurrente/LinkedBlockingQueue.take (LinkedBlockingQueue.java:413 (Compilado Código)) 4XESTACKTRACE en java/util/concurrente/ThreadPoolExecutor.getTask (ThreadPoolExecutor.java:958 (Compilado Código)) 4XESTACKTRACE en java/util/concurrente/ThreadPoolExecutor $ Worker.run (ThreadPoolExecutor.java:918) 4XESTACKTRACE en java/lang/Thread.run (Thread.java:736)

3XMTHREADINFO "H2 bloqueo de archivos Watchdog opt/myOrg/tomcat/webapps/MyApplication/db/myDatabase.lock.db" J9VMThread: 0x08DC6900, j9thread_t: 0x08C9BA24, ja
VA/lang/Tema: 0xE71E9018, Estado: CW, prio = 9 3XMTHREADINFO1
(Identificación nativa hilo: 0xA30, la prioridad orígenes: 0x9, la política nativa: DESCONOCIDO)
3XMTHREADINFO2 (rango de direcciones pila nativa de: 0xE5DBA000, a: 0xE5DFB000, tamaño: 0x41000) 3XMTHREADINFO3 Java pila de llamadas: 4XESTACKTRACE en java/lang/Tema .sleep (Método nativo) 4XESTACKTRACE
en java/lang/Thread.sleep (Thread.java:851 (código compilado))
4XESTACKTRACE en org/h2/store/Fil eLock.run (FileLock.java:490) 4XESTACKTRACE
en java/lang/Thread.run (Thread.java:736)

3XMTHREADINFO "FileWatchdog" J9VMThread: 0x087C0800, j9thread_t: 0x08C9B4FC, java/lang/Thread : 0xE715D878, Estado: CW, prio = 5
3XMTHREADINFO1 (ID hilo nativo: 0xA2C, nativo prioridad: 0x5, la política nativa: desconocido) 3XMTHREADINFO2
(rango de dirección de pila nativa a partir de: 0xE5E67000, a: 0xE5EA8000, tamaño: 0x41000) 3XMTHREADINFO3 Callstack de Java:
4XESTACKTRACE en java/lang/Thread.sleep (Método nativo) 4XESTACKTRACE en java/lang/Thread.sleep (Thread.java:851 (Compilado Código)) 4XESTACKTRACE en org// log4j/ayudantes/FileWatchdog.run (FileWatchdog.java:104)

+0

posible duplicado de [¡Juego! no cerrar H2 correctamente] (http://stackoverflow.com/questions/7182515/play-not-shutting-down-h2-correctly) –

+0

@MohamedMansour: He leído ese hilo pero no ayuda.1) Apagué el tomcat y no la aplicación. Entonces no debería haber conexiones abiertas 2) La respuesta parece ser un trabajo de campo y estoy tratando de entender si la fuerza de 'shutdown' a través de un comando SQL de un gancho es realmente el enfoque recomendado.No puedo decir desde el documento – Jim

+0

H2 invoca ['addShutdownHook()'] (http://docs.oracle.com/javase/6/docs/api/java/lang/Runtime.html#addShutdownHook%28java.lang .Highread% 29) para ti, usando una instancia de 'org.h2.engine.DatabaseCloser'. – trashgod

Respuesta

7

La documentación dice que la conexión H2 db se cierra cuando la máquina virtual sale normalmente. Y eso es lo que hace. El gancho de apagado ya está allí por defecto, no tienes que hacer nada.El cierre de cierre es una forma perfectamente válida de cerrar recursos que solo deben cerrarse al salir.

Si tiene .lock.db archivos restantes después del apagado, entonces la máquina virtual no salió normalmente. Usted escribió que el proceso no se detiene. Debe encontrar la razón para eso, porque probablemente eso también impida que se ejecute el gancho de cierre H2.

Con grandes bases de datos, el cierre podría tomar algún tiempo. Consulte con el depurador (por ejemplo, VisualVM) qué subprocesos permanecen activos después de que haya invocado (Tomcat) apagado.

Hay más posibilidad de: permisos de archivo se establecen de manera que puede H2 crear los archivos de bloqueo, pero no puede eliminar ellos. Si el sistema operativo evita que H2 elimine sus archivos de bloqueo, no hay mucho que H2 pueda hacer al respecto.

+0

Gracias. Intenté investigar por qué el proceso no se detiene (http://stackoverflow.com/questions/9971876/tomcat-doesnt-stop-how-can-i-debug-this) y terminé aquí. También en la carpeta hay un permiso 'rw-' para el usuario y '' r '' para el grupo. ¿Necesito el permiso 'x' para eliminarlo? – Jim

+0

'x' solo es necesario para ejecutar, no para borrar. Pero compruebe que el directorio no tenga [bit adhesivo] (http://www.thegeekstuff.com/2011/02/sticky-bit-on-directory-file/) establecido. –

+0

No, no hay 't' en el directorio. Y tomcat se está ejecutando con el usuario que es el propietario de los archivos. ¡Ahora estoy atascado! – Jim

1

No, un cierre Apache hook es simplemente un hilo que se ejecuta cuando termina la JVM, sin importar si regresa de main(), llama a System.exit (int) o lanza una excepción. Solo un bloqueo de JVM lo evitaría. Ver Runtime.addShutdownHook (Subproceso).

+0

Sé lo que es un gancho de apagado. No puedo decir si esta es la forma correcta de cerrar H2 – Jim

+0

@Jim: Si saber qué es un gancho de apagado, por qué lo preguntaste "* ¿es este el significado de shutdown hook? *" –

+0

@a_horse_with_no_name: quise decir en el contexto de cerrar 'H2'. No puedo encontrar un ejemplo para mostrar que debería agregar un enganche yo mismo – Jim

1

No estoy seguro de si esto es relevante para su situación, pero ¿ha intentado agregar un oyente de DBStarter?

http://www.h2database.com/html/tutorial.html, consulte la sección "Uso de un oyente de servlet para iniciar y detener una base de datos".

El enlace sugiere que se añada lo siguiente a web.xml:

<listener> 
    <listener-class>org.h2.server.web.DbStarter</listener-class> 
</listener> 

Por favor, véase la discusión aquí (la verdad a partir de 2008 por lo que puede estar fuera de fecha) - al parecer la solución se aplica a ambos casos incrustados y no incrustados : http://groups.google.com/group/h2-database/browse_thread/thread/eb609d58c96f4317

Alternativamente, ¿cómo está utilizando las conexiones? ¿Estás seguro de que estás limpiando las conexiones correctamente?

que estaba teniendo problemas antes, en mi caso yo estaba usando la conexión con una APP EntityManager y se me olvidó cerrar la instancia de EntityManager después de su uso, lo que dio lugar a algunos problemas:

@PersistenceUnit(unitName="myEm") 
private EntityManagerFactory emf; 

public void doStuff() { 
    EntityManager em = emf.createEntityManager(); 
    ... 
    em.close(); // forgot this line 
} 
1

puede ejecutar el declaración SHUTDOWN y luego cierre la conexión.

El comando SHUTDOWN hará que H2 libere todos los recursos relacionados con la conexión de inmediato. Eso, por ejemplo, le permitirá deshacerse de una base de datos H2 incorporada cuando vuelva a implementar una aplicación web.

2

Al observar el DbStarter.contextDestroyed() 'código de s (gracias a Allan5' s answer), aquí está el código que funcione:

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

Así Aaron Digulla 's answer era correcta (aunque no totalmente "copia/pastable ").

Además, si ha iniciado un servidor H2 TCP utilizando server = Server.createTcpServer("-tcpAllowOthers"), puede detenerlo simplemente usando server.stop().

Cuestiones relacionadas