2012-04-02 12 views
18

Điều này liên quan đến điều này post.
Tôi nghĩ rằng tôi đang gặp sự cố với H2 có nghĩa là nó không đóng đúng cách.
Tôi nghi ngờ điều này vì tôi thấy myDB.lock.db khi tôi tắt tomcat và quá trình này không dừng lại.
tôi sử dụng tổng hợp kết nối Tomcat và url cơ sở dữ liệu là:
url="jdbc:h2:file:/opt/myOrg/tomcat/webapps/MyApplication/db/myDatabase;SCHEMA=myschema"Cách thích hợp để đóng H2?

Từ doc close H2:

Thông thường, một cơ sở dữ liệu sẽ được đóng khi lần cuối kết nối với nó là kín .. .. Theo mặc định, một cơ sở dữ liệu bị đóng khi kết nối cuối cùng bị đóng. Tuy nhiên, nếu nó không bao giờ đóng, cơ sở dữ liệu sẽ đóng khi máy ảo thoát bình thường, sử dụng móc tắt máy

Tôi không thể hiểu được mình đang làm gì sai.
Tôi có nên buộc cơ sở dữ liệu đóng lại thông qua lệnh không? Đây có phải là ý nghĩa của việc tắt máy móc?
Tôi đang làm gì sai ở đây?

Lưu ý:
tôi không thể tìm thấy trong Google một ví dụ về làm thế nào để đóng H2 đúng cách (bên cạnh những tuyên bố rằng nó tự động đóng trên cuối cùng tắt máy kết nối). Tôi có nên gọi số SHUTDOWN không? Đây có phải là cách tiếp cận thích hợp không?
Tôi đã nhìn thấy phiếu để đóng câu hỏi nhưng vẫn chưa có một lý do hoặc liên kết trên một ví dụ về những gì tôi đang điều tra

UPDATE:
Sau Joonas Pulakka trả lời một số thông tin thêm:

Từ các javacore tôi đã sử dụng một kill -3 tôi thấy chủ đề:

"H2 Log Writer MYAPPLICATION" J9VMThread: 0x08DC6F00, j9thread_t: 0x08C9B790, java/lang/Th đọc: 0xE7206CC8, tiểu bang: CW, PRIO = 5 3XMTHREADINFO1 (có nguồn gốc chủ đề ID: 0xA32, có nguồn gốc ưu tiên: 0x5, chính sách bản địa: UNKNOWN) 3XMTHREADINFO2
(mẹ đẻ ngăn xếp dải địa chỉ từ: 0xE5E26000, để: 0xE5E67000, kích thước: 0x41000) callstack 3XMTHREADINFO3 Java:
4XESTACKTRACE tại java/lang/Object.wait (Native Method)
4XESTACKTRACE tại java/lang/Object.wait (Object.java:196 (Biên soạn Code)) 4XESTACKTRACE tại org/h2 /store/WriterThread.run(WriterThread.java:102)
4XESTACKTRACE tại java/lang/Thread.run (Chủ đề.java: 736)

3XMTHREADINFO "hồ bơi-8-thread-1" J9VMThread: 0x087C0200, j9thread_t: 0x0840566C, java/lang/Chủ đề: 0xE79BFC80, tiểu bang: P, PRIO = 5
3XMTHREADINFO1 (có nguồn gốc chủ đề ID: 0xE1A, có nguồn gốc ưu tiên: 0x5, chính sách bản địa: UNKNOWN) 3XMTHREADINFO2
(mẹ đẻ ngăn xếp dải địa chỉ từ: 0xE5F69000, để: 0xE5FAA000, kích thước: 0x41000) 3XMTHREADINFO3 Java callstack:
4XESTACKTRACE tại trời/misc/Unsafe.park (Phương thức gốc)
4XESTACKTRACE tại java/util/đồng thời/khóa/LockSupport.park (LockSupport.java:184 (Biên dịch Code)) 4XESTACKTRACE tại java/util/đồng/khóa/AbstractQueuedSynchronizer $ ConditionObject.await (AbstractQueuedSynchronizer.java:1998 (Biên soạn Code)) 4XESTACKTRACE tại java/util/đồng/LinkedBlockingQueue.take (LinkedBlockingQueue.java:413 (Biên soạn Mã)) 4XESTACKTRACE tại java/util/concurrent/ThreadPoolExecutor.getTask (ThreadPoolExecutor.java:958 (Biên soạn Mã)) 4XESTACKTRACE tại java/util/concurrent/ThreadPoolExecutor $ Worker.run (ThreadPoolExecutor.java:918) 4XESTACKTRACE tại java/lang/Thread.run (Thread.java:736)

3XMTHREADINFO "H2 Tệp khóa Cơ quan giám sát opt/myOrg/tomcat/webapps/MyApplication/db/myDatabase.lock.db" J9VMThread: 0x08DC6900, j9thread_t: 0x08C9BA24, ja
va/lang/Chủ đề: 0xE71E9018, tiểu bang: CW, PRIO = 9 3XMTHREADINFO1
(có nguồn gốc chủ đề ID: 0xA30, ưu tiên có nguồn gốc: 0x9, chính sách bản địa: UNKNOWN)
3XMTHREADINFO2 (mẹ đẻ ngăn xếp dải địa chỉ từ: 0xE5DBA000, tới: 0xE5DFB000, kích thước: 0x41000) 3XMTHREADINFO3 Java callstack: 4XESTACKTRACE tại java/lang/chủ đề .sleep (Native Method) 4XESTACKTRACE
tại java/lang/Thread.sleep (Thread.java:851 (Mã Biên dịch))
4XESTACKTRACE tại org/h2/store/Fil eLock.run (FileLock.java:490) 4XESTACKTRACE
tại java/lang/Thread.run (Thread.java:736)

3XMTHREADINFO "FileWatchdog" J9VMThread: 0x087C0800, j9thread_t: 0x08C9B4FC, java/lang/Chủ đề : 0xE715D878, tiểu bang: CW, PRIO = 5
3XMTHREADINFO1 (có nguồn gốc chủ đề ID: 0xA2C, có nguồn gốc ưu tiên: 0x5, chính sách bản địa: UNKNOWN) 3XMTHREADINFO2
(mẹ đẻ ngăn xếp dải địa chỉ từ: 0xE5E67000, để: 0xE5EA8000, kích thước: 0x41000) 3XMTHREADINFO3 Java callstack:
4XESTACKTRACE tại java/lang/Thread.sleep (Phương thức gốc) 4XESTACKTRACE tại java/lang/Thread.sleep (Thread.java:851 (Biên soạn Code)) 4XESTACKTRACE tại org/apache/log4j/giúp đỡ/FileWatchdog.run (FileWatchdog.java:104)

+0

bản sao có thể có của [Play! không tắt H2 đúng cách] (http://stackoverflow.com/questions/7182515/play-not-shutting-down-h2-correctly) –

+0

@MohamedMansour: Tôi đã đọc chủ đề đó nhưng không trợ giúp.1) Tôi tắt máy tomcat chứ không phải ứng dụng. Vì vậy, không nên có kết nối mở 2) Câu trả lời có vẻ là một công việc-arround và tôi đang cố gắng để hiểu nếu lực lượng 'shutdown' thông qua một lệnh SQL từ một móc thực sự là phương pháp được đề nghị.Tôi không thể nói từ tài liệu – Jim

+0

H2 gọi ['addShutdownHook()'] (http://docs.oracle.com/javase/6/docs/api/java/lang/Runtime.html#addShutdownHook%28java.lang .Thread% 29) cho bạn, sử dụng một thể hiện của 'org.h2.engine.DatabaseCloser'. – trashgod

Trả lời

7

Tài liệu nói rằng kết nối H2 db bị đóng khi máy ảo thoát bình thường. Và đó là những gì nó làm. Móc tắt máy đã có sẵn theo mặc định, bạn không phải làm bất cứ điều gì.Móc tắt máy là cách hoàn toàn hợp lệ để đóng tài nguyên chỉ cần đóng khi thoát.

Nếu bạn có .lock.db tệp còn lại sau khi tắt máy, thì máy ảo không thoát bình thường. Bạn đã viết rằng quá trình này không dừng lại. Bạn phải tìm lý do cho điều đó, bởi vì có lẽ đó là những gì cũng ngăn cản móc tắt máy H2 thực thi.

Với cơ sở dữ liệu lớn, việc đóng có thể mất chút thời gian. Xem với trình gỡ rối (ví dụ: VisualVM) những chủ đề nào vẫn hoạt động sau khi bạn đã tắt (Tomcat) tắt máy. Có thể có nhiều khả năng hơn: quyền truy cập tệp được đặt để H2 có thể tạo tệp khóa, nhưng không thể xóa chúng. Nếu hệ điều hành ngăn H2 xóa các tập tin khóa của nó thì không có nhiều H2 có thể làm được.

+0

Cảm ơn bạn. Tôi đã cố gắng điều tra lý do tại sao quy trình không dừng lại (http://stackoverflow.com/questions/9971876/tomcat-doesnt-stop-how-can-i-debug-this) và tôi đã kết thúc tại đây. Cũng trong thư mục có quyền 'rw-' cho người dùng và quyền 'r -' cho nhóm. Tôi có cần quyền 'x' để xóa không? – Jim

+0

'x' chỉ cần thiết để thực thi, không phải để xóa. Nhưng hãy kiểm tra xem thư mục không có [sticky bit] (http://www.thegeekstuff.com/2011/02/sticky-bit-on-directory-file/) được thiết lập chưa. –

+0

Không có 't' trong thư mục. Và tomcat đang chạy bằng cách sử dụng người dùng là chủ sở hữu của tập tin. Bây giờ tôi bị kẹt! – Jim

1

Không, ngừng hoạt động hook chỉ đơn giản là một thread chạy khi JVM chấm dứt, không có vấn đề nếu bằng cách trở về từ main(), gọi System.exit (int) hoặc ném một ngoại lệ. Chỉ có một vụ va chạm JVM sẽ tránh được nó. Xem Runtime.addShutdownHook (Chủ đề).

+0

Tôi biết móc khóa tắt là gì. Tôi không thể nói đây là cách thích hợp để đóng H2 – Jim

+0

@Jim: Nếu bạn biết móc tắt máy là gì, tại sao bạn hỏi "* đây có phải là ý nghĩa của móc tắt? *" –

+0

@a_horse_with_no_name: Tôi có nghĩa là trong bối cảnh tắt "H2'. Tôi không thể tìm thấy một ví dụ trên cho thấy rằng tôi nên thêm một cái móc bản thân mình – Jim

1

Bạn không chắc chắn điều này có liên quan đến tình huống của mình hay không nhưng bạn đã thử thêm người nghe DBStarter chưa?

http://www.h2database.com/html/tutorial.html, xem phần "Sử dụng trình nghe Servlet để bắt đầu và dừng cơ sở dữ liệu".

Các liên kết đề xuất thêm dòng sau vào web.xml:

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

Xin vui lòng xem thảo luận ở đây (thừa nhận từ năm 2008 như vậy có thể bị lỗi thời) - dường như việc sửa chữa được áp dụng cho cả hai trường hợp nhúng và không nhúng : http://groups.google.com/group/h2-database/browse_thread/thread/eb609d58c96f4317

Hoặc bạn sử dụng kết nối như thế nào? Bạn có chắc là bạn đang dọn dẹp các kết nối đúng cách không?

Tôi đã có những vấn đề trước đây, trong trường hợp của tôi, tôi đã sử dụng các kết nối với một JPA EntityManager và tôi quên đóng dụ EntityManager sau khi sử dụng, dẫn đến một số vấn đề:

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

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

Bạn có thể thực hiện tuyên bố SHUTDOWN và sau đó đóng kết nối.

Lệnh SHUTDOWN sẽ làm cho H2 miễn phí tất cả các tài nguyên liên quan đến kết nối ngay lập tức. Điều đó sẽ, ví dụ, cho phép bạn loại bỏ cơ sở dữ liệu H2 được nhúng khi bạn triển khai lại một ứng dụng web.

2

Bằng cách nhìn vào DbStarter.contextDestroyed() 'mã s (nhờ Allan5' s answer), đây là mã mà sẽ làm việc:

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

Vì vậy Aaron Digulla 's answer là đúng (ngay cả khi không hoàn toàn "sao chép/pastable ").

Hơn nữa, nếu bạn đã khởi động máy chủ kết nối H2 bằng cách sử dụng server = Server.createTcpServer("-tcpAllowOthers"), bạn có thể dừng nó chỉ đơn giản bằng cách sử dụng server.stop().

Các vấn đề liên quan