2013-06-19 11 views
6

Kiedy próbuje utworzyć nowe węzły w już istniejącej bazy danych, otrzymuję następujący wyjątek:Błąd Uzyskanie zamka (org.neo4j.kernal.StoreLockException)

org.neo4j.kernal.StoreLockException.

Poniższy fragment kodu jest linią, która powoduje, że wyjątek stanowi . Poniżej załączam trochę więcej szczegółów i pełny ślad stosu.

Jeśli utworzę nowy folder i użyję go jako DB_PATH, mój kod działa poprawnie przy pierwszym uruchomieniu. W drugim uruchomieniu wystąpi błąd z tym samym wyjątkiem. Wygląda na to, że coś uniemożliwia uzyskanie blokady.

Próbowałem ustawić uprawnienia do odczytu/zapisu dla każdego pliku w DB_PATH. Brak szczęścia. Czy w jednym z plików konfiguracyjnych jest ustawienie, które musi być wyłączone w odniesieniu do blokad?

Kod rzucanie Wyjątek

graphDB = new GraphDatabaseFactory().newEmbeddedDatabase(DB_PATH); 

Więcej szczegółów (linia 6)

private static GraphDatabaseService graphDB = null; 
public static final String DB_PATH = "/Users/NtroduceMe/Downloads/neo4j-community-2.0.0-M03/data/ntroduceme"; 
private static Index<Node> userNodeIndex; 
private static Index<Node> rememberMeNodeIndex; 
static { 
    graphDB = new GraphDatabaseFactory().newEmbeddedDatabase(DB_PATH); 
    registerShutdownHook(graphDB); 
    userNodeIndex = graphDB.index().forNodes("profile_id"); 
    rememberMeNodeIndex = graphDB.index().forNodes("profile_id"); 
} 

Śledzenie stosu

Jun 19, 2013 12:12:50 AM org.apache.catalina.core.StandardWrapperValve invoke 
SEVERE: Servlet.service() for servlet [ProfileController] in context with path [] threw exception [Servlet execution threw an exception] with root cause 
org.neo4j.kernel.StoreLockException: Could not create lock file 
    at org.neo4j.kernel.StoreLocker.checkLock(StoreLocker.java:85) 
    at org.neo4j.kernel.StoreLockerLifecycleAdapter.start(StoreLockerLifecycleAdapter.java:40) 
    at org.neo4j.kernel.lifecycle.LifeSupport$LifecycleInstance.start(LifeSupport.java:498) 
    at org.neo4j.kernel.lifecycle.LifeSupport.start(LifeSupport.java:115) 
    at org.neo4j.kernel.InternalAbstractGraphDatabase.run(InternalAbstractGraphDatabase.java:296) 
    at org.neo4j.kernel.EmbeddedGraphDatabase.<init>(EmbeddedGraphDatabase.java:100) 
    at org.neo4j.graphdb.factory.GraphDatabaseFactory$1.newDatabase(GraphDatabaseFactory.java:92) 
    at org.neo4j.graphdb.factory.GraphDatabaseBuilder.newGraphDatabase(GraphDatabaseBuilder.java:197) 
    at org.neo4j.graphdb.factory.GraphDatabaseFactory.newEmbeddedDatabase(GraphDatabaseFactory.java:69) 
    at com.NtroduceMe.Utilities.GraphDBManager.<clinit>(GraphDBManager.java:22) 
    at com.NtroduceMe.UserProfile.Profiles.createProfile(Profiles.java:141) 
    at com.NtroduceMe.UserProfile.ProfileController.doPost(ProfileController.java:61) 
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:647) 
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:728) 
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305) 
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210) 
    at org.netbeans.modules.web.monitor.server.MonitorFilter.doFilter(MonitorFilter.java:393) 
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243) 
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210) 
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222) 
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123) 
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472) 
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171) 
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99) 
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:936) 
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118) 
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407) 
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1004) 
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:589) 
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:312) 
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) 
    at java.lang.Thread.run(Thread.java:722) 

Helper Class użyć do zapisania bazy danych instancji

public class GraphDBManager { 
    public static final String DB_PATH = "/Users/NtroduceMe/Downloads/neo4j-community-2.0.0-M03/data/ntroduceme"; 
    private static final GraphDatabaseService graphDB = new GraphDatabaseFactory().newEmbeddedDatabase(DB_PATH);  
    private static Index<Node> userNodeIndex; 
    private static Index<Node> rememberMeNodeIndex; 
    static { 
     registerShutdownHook(graphDB); 
     userNodeIndex = graphDB.index().forNodes("profile_id"); 
     rememberMeNodeIndex = graphDB.index().forNodes("profile_id"); 
    } 

    public static GraphDatabaseService getGraphDB(){ 
     return graphDB; 
    } 

    public static Index<Node> getUserNodeIndex(){ 
     return userNodeIndex; 
    } 

    public static Index<Node> getRemberMeNodeIndex(){ 
     return rememberMeNodeIndex; 
    } 

    private static void registerShutdownHook(final GraphDatabaseService graphDb) 
    { 
     // Registers a shutdown hook for the Neo4j instance so that it 
     // shuts down nicely when the VM exits (even if you "Ctrl-C" the 
     // running application). 
     Runtime.getRuntime().addShutdownHook(new Thread() 
     { 
      @Override 
      public void run() 
      { 
       graphDb.shutdown(); 
      } 
     }); 
    } 

} 
+0

Witaj, rozwiązałeś problem? Teraz mam ten sam problem. – gozizibj

+0

Jakiś czas temu przełączyłem się na API Bolt i nie miałem tego problemu. Wierzę, że zainstalowałem neo przy użyciu sudo, używając najnowszej wersji, a nie pojedynczego problemu z instalacją. –

+0

Również nie używam już osadzonych. –

Odpowiedz

1

nie są prawidłowo zamykanie bazy danych, gdy program się kończy, więc odchodzi plik blokady tam.

Można rozważyć utworzenie hak wyłączania opisanej tutaj: http://docs.neo4j.org/chunked/stable/tutorials-java-embedded-setup.html#tutorials-java-embedded-setup-startstop

+0

Mam już wywołanie zamknięcia haka. Próbowałem ponownie uruchomić z usuniętym shutdownhook i pojawia się ten sam błąd. Nie sądzę, żeby miało to coś wspólnego z ShutdownHook. To nie powinno być wywoływane, chyba że cała moja aplikacja zamyka się poprawnie? Nie mam zamiaru rozpoczynać i zatrzymywać bazy danych pomiędzy zapytaniami? Sposób, w jaki mam to ustawienie, polega na tym, że moja aplikacja internetowa uruchamia bazę danych raz, gdy wszystkie klasy są zainicjowane, a następnie rejestruje haki zamykające, tak aby zamknęła bazę danych, jeśli maszyna wirtualna zostanie zamknięta. Czy po każdej transakcji mam wyłączać? –

+1

Hmm, nie - Przypuszczam, że to nie jest problem. –

1

Zastanawiam się tylko, dlaczego wyłączenie DB przed utworzeniem węzłów?

Nie można tworzyć węzły użyciu zamkniętego DB, więc może to być tak:

graphDB = new GraphDatabaseFactory().newEmbeddedDatabase(DB_PATH); 
userNodeIndex = graphDB.index().forNodes("profile_id"); 
rememberMeNodeIndex = graphDB.index().forNodes("profile_id"); 
Transaction tx = graphDb.beginTx(); 
try 
    { 
    Node node = graphDb.createNode(); 
    node.setProperty(USER_ID, "userID"); 
    nodeIndex.add(node, USER_ID, "userID"); 
    } 

i po fininsh tworząc wszystkie węzły, można zadzwonić:

registerShutdownHook(graphDB); 
+1

Myślałem, że celem funkcji registerShutdownHook było działanie jak wywołanie zwrotne, które jest wywoływane tylko po wyjściu VM? Więc wywołanie go faktycznie wyłącza db? –

+0

oczywiście zamknięcie DB, to kod jest jak ten 'private static void registerShutdownHook (końcowe GraphDatabaseService graphDb) { Runtime.getRuntime(). AddShutdownHook (nowego wątku() { @Override public void run () { graphDb.shutdown(); } }); } ' Jak widać, po prostu zamknie uruchomiony DB .. –

+0

Rozumiem. Źle nazwana funkcja. Termin "zarejestruj się" przeze mnie. Spróbuję tego. –

1

I don wiesz, co się stało, ale czy możesz po prostu sprawdzić, czy w twoim katalogu graphdb znajduje się plik "store_lock", a jeśli nie, po prostu go utworzyć (za pomocą polecenia "touch") lub coś w tym stylu? To powinno rozwiązać problem.

+0

Tak, jest plik store_lock –

+0

I dodałem trochę więcej kodu, ale zasadniczo przenoszę instancję db dookoła w bloku statycznym klasy pomocnika. Błąd zostanie zgłoszony natychmiast w momencie tworzenia bazy danych. Używam lwa górskiego Mac OSX. –

1

Nie jestem pewien, czy wciąż szukasz rozwiązania, czy nie, ale podczas pracy nad projektem natknąłem się na ten sam problem. Zdarza się to, jeśli baza danych nie jest poprawnie zamknięta po zakończeniu programu lub jeśli zarejestrowałeś zamknięcie, pojawia się po tym jak proces zostanie w jakiś sposób przymusowo zakończony (przez jakiegoś ..... bardzo ... rozważnego ... kolegium na przykład) więc hak nigdy nie zostanie wywołany. Oznacza to, że będziesz musiał zwolnić blokadę podczas następnego uruchomienia programu. A więc oto mój kod do tego, mam nadzieję, że nadal pomaga komuś w jakiś sposób.

StoreLocker lock = new StoreLocker(new DefaultFileSystemAbstraction()); 
     lock.checkLock(new File(DB_Location)); 
     try { 
      lock.release(); 
      graph = new GraphDatabaseFactory().newEmbeddedDatabase(DB_Location); 
     } catch (IOException e1) { 
      e1.printStackTrace(); 
     } 

Oczywiście powinieneś mówić tylko wtedy, gdy coś podczas otwierania bazy poszło nie tak! I to powinno być jasne, ale powiem to tak czy inaczej, żeby mieć pewność. Ten sam błąd występuje, jeśli istnieją dwie lub więcej instancji twojego programu, użycie tego sposobu zwalniania blokady w takim przypadku spowoduje dalsze problemy!

1

W podręczniku Neo4j:

Instancja EmbeddedGraphDatabase mogą być współużytkowane przez wiele wątkach. Należy jednak pamiętać, że nie można utworzyć wielu wystąpień, wskazując na tę samą bazę danych.

I miałem ten błąd po prostu dlatego, że uruchomiłem serwer Neo4j przed wdrożeniem aplikacji. Zaraz po uruchomieniu serwera Neo4j zostanie utworzony pusty plik "lock" i umieszczony w katalogu bazy danych.

Więc przypuszczam, że jest ponieważ instancja została już utworzona, a ja starałem się stworzyć nową instancję przez moją aplikacji Java, która jest niemożliwe.