2012-04-02 25 views
18

Questo è collegato a questo post.
Penso di avere problemi con H2 che significa che non si chiude correttamente.
Ho il sospetto che poiché vedo myDB.lock.db quando spengo Tomcat e il processo non si ferma.
Io uso il pool di connessioni di Tomcat e l'URL al database è:
url="jdbc:h2:file:/opt/myOrg/tomcat/webapps/MyApplication/db/myDatabase;SCHEMA=myschema"Qual è il modo corretto per chiudere H2?

Dal doc close H2:

Di solito, un database viene chiuso quando l'ultimo collegamento ad essa è chiuso .. .. Per impostazione predefinita, un database è chiuso quando l'ultima connessione è chiusa. Tuttavia, se non è mai chiusa, il database viene chiuso quando la macchina virtuale si chiude normalmente, con un gancio di arresto

Non riesco a capire se sto facendo qualcosa di sbagliato.
Devo forzare la chiusura del database tramite un comando? È questo il significato del gancio di arresto?
Cosa sto facendo male qui?

Nota:
Non riesco a trovare in Google un esempio di come chiudere H2 correttamente (oltre l'affermazione che si chiude automaticamente in ultimo arresto di connessione). Devo chiamare lo SHUTDOWN da solo? È questo l'approccio corretto?
Vedo già voti per chiudere la questione, ma non c'è stato un motivo o un link su un esempio di quello che sto studiando

UPDATE:
Dopo Joonas Pulakka a rispondere ad alcune informazioni in più:

Da il javacore ho ottenuto utilizzando un kill -3 vedo i fili:

"H2 Log Writer myapplication" J9VMThread: 0x08DC6F00, j9thread_t: 0x08C9B790, java/lang/Th leggi: 0xE7206CC8, Stato: CW, prio = 5 3XMTHREADINFO1 (nativo ID filetto: 0xA32, nativo priorità: 0x5, politica origini: NOTO) 3XMTHREADINFO2
(nativo intervallo di indirizzi pila da: 0xE5E26000, a: 0xE5E67000, dimensioni: 0x41000) 3XMTHREADINFO3 Java stack:
4XESTACKTRACE in java/lang/Object.wait (metodo natale)
4XESTACKTRACE a java/lang/Object.wait (Object.java:196 (Compiled Codice)) 4XESTACKTRACE a org/h2 /store/WriterThread.run(WriterThread.java:102)
4XESTACKTRACE a java/lang/Thread.run (Thread.java: 736)

3XMTHREADINFO "pool-8-thread-1" J9VMThread: 0x087C0200, j9thread_t: 0x0840566C, java/lang/Discussione: 0xE79BFC80, Stato: P, prio = 5
3XMTHREADINFO1 (ID thread nativo: 0xE1A, nativo priorità: 0x5, la politica origini: UNKNOWN) 3XMTHREADINFO2
(nativo intervallo di indirizzi di stack da: 0xE5F69000, a: 0xE5FAA000, dimensioni: 0x41000) 3XMTHREADINFO3 Java stack:
4XESTACKTRACE al sole/misc/Unsafe.park (Metodo nativo)
4XESTACKTRACE a java/util/simultaneo/lock/LockSupport.park (LockSupport.java:184 (compilato Codice)) 4XESTACKTRACE a java/util/concorrente/serrature/AbstractQueuedSynchronizer $ ConditionObject.await (AbstractQueuedSynchronizer.java:1998 (compilato Codice)) 4XESTACKTRACE a java/util/concorrente/LinkedBlockingQueue.take (LinkedBlockingQueue.java:413 (Compiled Codice)) 4XESTACKTRACE a java/util/concorrente/ThreadPoolExecutor.getTask (ThreadPoolExecutor.java:958 (Compiled Codice)) 4XESTACKTRACE a java/util/concorrente/ThreadPoolExecutor $ Worker.run (ThreadPoolExecutor.java:918 4XESTACKTRACE a java/lang/Thread.run (Thread.java:736)

3XMTHREADINFO "H2 File Lock Watchdog opt/myOrg/tomcat/webapps/MyApplication/db/myDatabase.lock.db" J9VMThread: 0x08DC6900, j9thread_t: 0x08C9BA24, ja
VA/lang/Discussione: 0xE71E9018, Stato: CW, prio = 9 3XMTHREADINFO1
(ID nativo filo: 0xA30, la priorità origini: 0x9, la politica origini: UNKNOWN)
3XMTHREADINFO2 (nativo intervallo di indirizzi di stack da: 0xE5DBA000, a: 0xE5DFB000, dimensioni: 0x41000) 3XMTHREADINFO3 Java callstack: 4XESTACKTRACE a java/lang/Discussione .sleep (metodo nativo) 4XESTACKTRACE
a java/lang/Thread.sleep (Thread.java:851 (codice compilato))
4XESTACKTRACE a org/h2/store/Fil eLock.run (FileLock.java:490) 4XESTACKTRACE
in java/lang/Thread.run (Thread.java:736)

3XMTHREADINFO "FileWatchdog" J9VMThread: 0x087C0800, j9thread_t: 0x08C9B4FC, java/lang/Discussione : 0xE715D878, stato: CW, prio = 5
3XMTHREADINFO1 (nativo ID filetto: 0xA2C, nativo priorità: 0x5, politica origini: NOTO) 3XMTHREADINFO2
(nativo intervallo di indirizzi pila da: 0xE5E67000, a: 0xE5EA8000, dimensioni: 0x41000) 3XMTHREADINFO3 Callstack Java:
4XESTACKTRACE a java/lang/Thread.sleep (metodo nativo) 4XESTACKTRACE a java/lang/Thread.sleep (Thread.java:851 (Compiled Codice)) 4XESTACKTRACE a org/apache/log4j/aiutanti/FileWatchdog.run (FileWatchdog.java:104)

+0

possibile duplicato di [Play! non chiudendo correttamente H2] (http://stackoverflow.com/questions/7182515/play-not-shutting-down-h2-correctly) –

+0

@MohamedMansour: ho letto quella discussione ma non aiuta.1) I shutdown tomcat e non l'applicazione. Quindi non ci dovrebbero essere connessioni aperte 2) La risposta sembra essere un arsenale di lavoro e sto cercando di capire se la forza di 'shutdown' tramite un comando SQL da un hook è in realtà l'approccio consigliato.Non posso dire dal doc – Jim

+0

H2 invoca ['addShutdownHook()'] (http://docs.oracle.com/javase/6/docs/api/java/lang/Runtime.html#addShutdownHook%28java.lang .Thread% 29) per te, usando un'istanza di 'org.h2.engine.DatabaseCloser'. – trashgod

risposta

7

La documentazione dice che la connessione H2 db viene chiusa quando la macchina virtuale esce normalmente. E questo è quello che fa. Il gancio di spegnimento è già lì per impostazione predefinita, non devi fare nulla.Il gancio di arresto è un modo perfettamente valido per chiudere le risorse che devono essere chiuse solo quando si esce.

Se si dispone dei file .lock.db rimanenti dopo l'arresto, la macchina virtuale non si è chiusa normalmente. Hai scritto che il processo non si ferma. Devi trovare la ragione per questo, perché probabilmente questo è anche ciò che impedisce l'esecuzione del gancio di arresto H2.

Con grandi database, la chiusura potrebbe richiedere del tempo. Vedi con debugger (ad es. VisualVM) quali thread rimangono attivi dopo l'invocazione (Tomcat).

C'è in più possibilità: permessi dei file sono impostate in modo tale che H2 può creare i file di lock, ma non possibile eliminare loro. Se il sistema operativo impedisce a H2 di eliminare i suoi file di blocco, non c'è molto che H2 possa fare al riguardo.

+0

Grazie. Stavo cercando di capire perché il processo non si fermava (http://stackoverflow.com/questions/9971876/tomcat-doesnt-stop-how-can-i-debug-questo) e sono finito qui. Inoltre nella cartella c'è il permesso 'rw-' per l'utente e 'r -' permesso al gruppo. Ho bisogno del permesso 'x' per cancellare? – Jim

+0

'x' è necessario solo per l'esecuzione, non per l'eliminazione. Ma controlla che la directory non abbia impostato [sticky bit] (http://www.thegeekstuff.com/2011/02/sticky-bit-on-directory-file/). –

+0

No non c'è 't' nella directory.E tomcat è in esecuzione utilizzando l'utente che è il proprietario dei file.Ora sono bloccato! – Jim

1

No, un arresto hook è semplicemente un thread che viene eseguito quando termina la JVM, indipendentemente dal ritorno da main(), chiamando System.exit (int) o generando un'eccezione. Solo un arresto JVM lo eviterebbe. Vedi Runtime.addShutdownHook (Thread).

+0

So che cosa è un hook di chiusura. Non posso dire se questo è il modo corretto per chiudere H2 – Jim

+0

@Jim: Se sapere cos'è un hook di shutdown, perché hai chiesto "* è questo il significato di hook di shutdown? *" –

+0

@a_horse_with_no_name: intendevo nel contesto dello shuting di 'H2'. Non riesco a trovare un esempio sul mostrare che io dovrei aggiungere un gancio io stesso – Jim

1

Non sei sicuro se questo è rilevante per la tua situazione ma hai provato ad aggiungere un listener DBStarter?

http://www.h2database.com/html/tutorial.html, vedere la sezione "Utilizzo di un listener servlet per avviare e arrestare un database".

Il collegamento suggerisce di aggiungere quanto segue a web.xml:

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

Si prega di consultare la discussione qui (certamente a partire dal 2008 per evitare di essere aggiornati) - a quanto pare la correzione vale per entrambe le istanze incorporati e non incorporati : http://groups.google.com/group/h2-database/browse_thread/thread/eb609d58c96f4317

In alternativa, come si utilizzano le connessioni? Sei sicuro di aver pulito i collegamenti correttamente?

ho avuto problemi prima, nel mio caso ho usato la connessione con un JPA EntityManager e ho dimenticato di chiudere l'istanza EntityManager dopo l'uso, che ha provocato alcuni problemi:

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

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

È possibile eseguire il dichiarazione SHUTDOWN e quindi chiudere la connessione.

Il comando SHUTDOWN renderà H2 libero da tutte le risorse correlate alla connessione. Ciò consentirà, ad esempio, di eliminare un database H2 incorporato quando si ridistribuisce un'applicazione Web.

2

Osservando la DbStarter.contextDestroyed() 'codice di s (grazie a Allan5' s answer), qui è il codice che funziona:

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

Così Aaron Digulla s' answer era corretta (anche se non del tutto "copia/pastable ").

Inoltre, se avete iniziato un server TCP H2 usando server = Server.createTcpServer("-tcpAllowOthers"), si può fermare semplicemente utilizzando server.stop().